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.
Project: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/commit/e365f11b Tree: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/tree/e365f11b Diff: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/diff/e365f11b Branch: refs/heads/3 Commit: e365f11bd39dcf5566ff04c7ad8ec08782b81b48 Parents: 3de10f7 Author: ddekany <[email protected]> Authored: Sun Mar 19 16:48:43 2017 +0100 Committer: ddekany <[email protected]> Committed: Sun Mar 19 21:04:17 2017 +0100 ---------------------------------------------------------------------- .../apache/freemarker/core/ASTDirInclude.java | 62 ++-------- .../apache/freemarker/core/Configuration.java | 105 +++++++++-------- .../org/apache/freemarker/core/Environment.java | 24 ++-- .../apache/freemarker/core/ParameterRole.java | 1 - .../freemarker/core/ParserConfiguration.java | 2 + .../org/apache/freemarker/core/Template.java | 62 +--------- .../freemarker/core/TemplateConfiguration.java | 32 +++++- .../freemarker/core/TemplateLanguage.java | 103 +++++++++++++++++ .../core/TemplateNotFoundException.java | 2 +- .../core/WrongTemplateCharsetException.java | 61 ++++++++++ ..._ParserConfigurationWithInheritedFormat.java | 5 + .../templateresolver/GetTemplateResult.java | 2 +- .../templateresolver/TemplateLoaderSession.java | 2 +- .../templateresolver/TemplateLookupContext.java | 2 +- .../core/templateresolver/TemplateResolver.java | 8 +- .../impl/DefaultTemplateResolver.java | 112 +++++++++---------- src/main/javacc/FTL.jj | 14 +-- src/manual/en_US/FM3-CHANGE-LOG.txt | 7 +- .../freemarker/core/ConfigurationTest.java | 74 ++---------- .../freemarker/core/TemplatGetEncodingTest.java | 16 ++- .../core/TemplateConfigurationTest.java | 35 +++++- .../core/TemplateConstructorsTest.java | 2 +- .../core/TemplateLookupStrategyTest.java | 20 ++-- .../core/TemplateNotFoundMessageTest.java | 2 +- .../DefaultTemplateResolverTest.java | 14 +-- .../test/templatesuite/expected/include.txt | 13 --- .../test/templatesuite/expected/include2.txt | 11 -- .../test/templatesuite/templates/include.ftl | 2 - .../test/templatesuite/templates/include2.ftl | 17 +-- 29 files changed, 429 insertions(+), 383 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/e365f11b/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 68c376b..9a51f16 100644 --- a/src/main/java/org/apache/freemarker/core/ASTDirInclude.java +++ b/src/main/java/org/apache/freemarker/core/ASTDirInclude.java @@ -33,20 +33,18 @@ import org.apache.freemarker.core.util._StringUtil; */ final class ASTDirInclude extends ASTDirective { - private final ASTExpression includedTemplateNameExp, encodingExp, parseExp, ignoreMissingExp; + private final ASTExpression includedTemplateNameExp, encodingExp, ignoreMissingExp; private final String encoding; - private final Boolean parse; 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. - * @param parseExp whether the template should be parsed (or is raw text) */ ASTDirInclude(Template template, ASTExpression includedTemplateNameExp, - ASTExpression encodingExp, ASTExpression parseExp, ASTExpression ignoreMissingExp) throws ParseException { + ASTExpression encodingExp, ASTExpression ignoreMissingExp) throws ParseException { this.includedTemplateNameExp = includedTemplateNameExp; this.encodingExp = encodingExp; @@ -69,33 +67,7 @@ final class ASTDirInclude extends ASTDirective { encoding = null; } } - - this.parseExp = parseExp; - if (parseExp == null) { - parse = Boolean.TRUE; - } else { - if (parseExp.isLiteral()) { - try { - if (parseExp instanceof ASTExpStringLiteral) { - // Legacy - parse = Boolean.valueOf(_StringUtil.getYesNo(parseExp.evalAndCoerceToPlainText(null))); - } else { - try { - parse = Boolean.valueOf(parseExp.evalToBoolean(template.getConfiguration())); - } catch (NonBooleanException e) { - throw new ParseException("Expected a boolean or string as the value of the parse attribute", - parseExp, e); - } - } - } catch (TemplateException e) { - // evaluation of literals must not throw a TemplateException - throw new BugException(e); - } - } else { - parse = null; - } - } - + this.ignoreMissingExp = ignoreMissingExp; if (ignoreMissingExp != null && ignoreMissingExp.isLiteral()) { try { @@ -133,19 +105,6 @@ final class ASTDirInclude extends ASTDirective { ? encodingExp.evalAndCoerceToPlainText(env) : null); - final boolean parse; - if (this.parse != null) { - parse = this.parse.booleanValue(); - } else { - TemplateModel tm = parseExp.eval(env); - if (tm instanceof TemplateScalarModel) { - // Legacy - parse = getYesNo(parseExp, _EvalUtil.modelToString((TemplateScalarModel) tm, parseExp, env)); - } else { - parse = parseExp.modelToBoolean(tm, env); - } - } - final boolean ignoreMissing; if (ignoreMissingExpPrecalcedValue != null) { ignoreMissing = ignoreMissingExpPrecalcedValue.booleanValue(); @@ -157,7 +116,7 @@ final class ASTDirInclude extends ASTDirective { final Template includedTemplate; try { - includedTemplate = env.getTemplateForInclusion(fullIncludedTemplateName, encoding, parse, ignoreMissing); + includedTemplate = env.getTemplateForInclusion(fullIncludedTemplateName, encoding, ignoreMissing); } catch (IOException e) { throw new _MiscTemplateException(e, env, "Template inclusion failed (for parameter value ", @@ -181,9 +140,6 @@ final class ASTDirInclude extends ASTDirective { if (encodingExp != null) { buf.append(" encoding=").append(encodingExp.getCanonicalForm()); } - if (parseExp != null) { - buf.append(" parse=").append(parseExp.getCanonicalForm()); - } if (ignoreMissingExp != null) { buf.append(" ignore_missing=").append(ignoreMissingExp.getCanonicalForm()); } @@ -205,9 +161,8 @@ final class ASTDirInclude extends ASTDirective { Object getParameterValue(int idx) { switch (idx) { case 0: return includedTemplateNameExp; - case 1: return parseExp; - case 2: return encodingExp; - case 3: return ignoreMissingExp; + case 1: return encodingExp; + case 2: return ignoreMissingExp; default: throw new IndexOutOfBoundsException(); } } @@ -216,9 +171,8 @@ final class ASTDirInclude extends ASTDirective { ParameterRole getParameterRole(int idx) { switch (idx) { case 0: return ParameterRole.TEMPLATE_NAME; - case 1: return ParameterRole.PARSE_PARAMETER; - case 2: return ParameterRole.ENCODING_PARAMETER; - case 3: return ParameterRole.IGNORE_MISSING_PARAMETER; + case 1: return ParameterRole.ENCODING_PARAMETER; + case 2: return ParameterRole.IGNORE_MISSING_PARAMETER; default: throw new IndexOutOfBoundsException(); } } http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/e365f11b/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 3d1665a..e58ca5b 100644 --- a/src/main/java/org/apache/freemarker/core/Configuration.java +++ b/src/main/java/org/apache/freemarker/core/Configuration.java @@ -216,6 +216,13 @@ public class Configuration extends Configurable implements Cloneable, ParserConf public static final String AUTO_INCLUDE_KEY = AUTO_INCLUDE_KEY_SNAKE_CASE; /** Legacy, snake case ({@code like_this}) variation of the setting name. @since 2.3.23 */ + public static final String TEMPLATE_LANGUAGE_KEY_SNAKE_CASE = "template_language"; + /** Modern, camel case ({@code likeThis}) variation of the setting name. @since 2.3.23 */ + public static final String TEMPLATE_LANGUAGE_KEY_CAMEL_CASE = "templateLanguage"; + /** Alias to the {@code ..._SNAKE_CASE} variation due to backward compatibility constraints. */ + public static final String TEMPLATE_LANGUAGE_KEY = TEMPLATE_LANGUAGE_KEY_SNAKE_CASE; + + /** Legacy, snake case ({@code like_this}) variation of the setting name. @since 2.3.23 */ public static final String TAG_SYNTAX_KEY_SNAKE_CASE = "tag_syntax"; /** Modern, camel case ({@code likeThis}) variation of the setting name. @since 2.3.23 */ public static final String TAG_SYNTAX_KEY_CAMEL_CASE = "tagSyntax"; @@ -285,6 +292,7 @@ public class Configuration extends Configurable implements Cloneable, ParserConf TAB_SIZE_KEY_SNAKE_CASE, TAG_SYNTAX_KEY_SNAKE_CASE, TEMPLATE_CONFIGURATIONS_KEY_SNAKE_CASE, + TEMPLATE_LANGUAGE_KEY_SNAKE_CASE, TEMPLATE_LOADER_KEY_SNAKE_CASE, TEMPLATE_LOOKUP_STRATEGY_KEY_SNAKE_CASE, TEMPLATE_NAME_FORMAT_KEY_SNAKE_CASE, @@ -306,6 +314,7 @@ public class Configuration extends Configurable implements Cloneable, ParserConf TAB_SIZE_KEY_CAMEL_CASE, TAG_SYNTAX_KEY_CAMEL_CASE, TEMPLATE_CONFIGURATIONS_KEY_CAMEL_CASE, + TEMPLATE_LANGUAGE_KEY_CAMEL_CASE, TEMPLATE_LOADER_KEY_CAMEL_CASE, TEMPLATE_LOOKUP_STRATEGY_KEY_CAMEL_CASE, TEMPLATE_NAME_FORMAT_KEY_CAMEL_CASE, @@ -401,6 +410,7 @@ public class Configuration extends Configurable implements Cloneable, ParserConf private Boolean recognizeStandardFileExtensions; private Map<String, ? extends OutputFormat> registeredCustomOutputFormats = Collections.emptyMap(); private Version incompatibleImprovements; + private TemplateLanguage templateLanguage = TemplateLanguage.FTL; private int tagSyntax = ANGLE_BRACKET_TAG_SYNTAX; private int namingConvention = AUTO_DETECT_NAMING_CONVENTION; private int tabSize = 8; // Default from JavaCC 3.x @@ -1712,6 +1722,23 @@ public class Configuration extends Configurable implements Cloneable, ParserConf } /** + * Getter pair of {@link #setTemplateLanguage(TemplateLanguage)}. + */ + @Override + public TemplateLanguage getTemplateLanguage() { + return templateLanguage; + } + + /** + * Sets the template language used; this is often overridden for certain file extension with + * {@link #setTemplateConfigurations(TemplateConfigurationFactory)}. + */ + public void setTemplateLanguage(TemplateLanguage templateLanguage) { + _NullArgumentException.check("templateLanguage", templateLanguage); + this.templateLanguage = templateLanguage; + } + + /** * Determines the syntax of the template files (angle bracket VS square bracket) * that has no {@code #ftl} in it. The {@code tagSyntax} * parameter must be one of: @@ -1867,62 +1894,53 @@ public class Configuration extends Configurable implements Cloneable, ParserConf * missing/staled. * * <p> - * This is a shorthand for {@link #getTemplate(String, Locale, Object, String, boolean, boolean) - * getTemplate(name, null, null, null, true, false)}; see more details there. + * This is a shorthand for {@link #getTemplate(String, Locale, Object, String, boolean) + * getTemplate(name, null, 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, true, false); + return getTemplate(name, null, null, null, false); } /** - * Shorthand for {@link #getTemplate(String, Locale, Object, String, boolean, boolean) - * getTemplate(name, locale, null, null, true, false)}. + * Shorthand for {@link #getTemplate(String, Locale, Object, String, 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, true, false); + return getTemplate(name, locale, null, null, false); } /** - * Shorthand for {@link #getTemplate(String, Locale, Object, String, boolean, boolean) - * getTemplate(name, null, null, encoding, true, false)}. + * Shorthand for {@link #getTemplate(String, Locale, Object, String, boolean) + * getTemplate(name, null, null, encoding, false)}. */ public Template getTemplate(String name, String encoding) throws TemplateNotFoundException, MalformedTemplateNameException, ParseException, IOException { - return getTemplate(name, null, null, encoding, true, false); + return getTemplate(name, null, null, encoding, false); } /** - * Shorthand for {@link #getTemplate(String, Locale, Object, String, boolean, boolean) - * getTemplate(name, locale, null, encoding, true, 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, true, false); - } - - /** - * Shorthand for {@link #getTemplate(String, Locale, Object, String, boolean, boolean) - * getTemplate(name, locale, null, encoding, parseAsFTL, false)}. - */ - public Template getTemplate(String name, Locale locale, String encoding, boolean parseAsFTL) - throws TemplateNotFoundException, MalformedTemplateNameException, ParseException, IOException { - return getTemplate(name, locale, null, encoding, parseAsFTL, false); + return getTemplate(name, locale, null, encoding, false); } /** - * Shorthand for {@link #getTemplate(String, Locale, Object, String, boolean, boolean) - * getTemplate(name, locale, null, encoding, parseAsFTL, ignoreMissing)}. + * Shorthand for {@link #getTemplate(String, Locale, Object, String, boolean) + * getTemplate(name, locale, null, encoding, ignoreMissing)}. * * @since 2.3.21 */ - public Template getTemplate(String name, Locale locale, String encoding, boolean parseAsFTL, boolean ignoreMissing) + public Template getTemplate(String name, Locale locale, String encoding, boolean ignoreMissing) throws TemplateNotFoundException, MalformedTemplateNameException, ParseException, IOException { - return getTemplate(name, locale, null, encoding, parseAsFTL, ignoreMissing); + return getTemplate(name, locale, null, encoding, ignoreMissing); } /** @@ -1991,11 +2009,6 @@ public class Configuration extends Configurable implements Cloneable, ParserConf * extension, etc.). The encoding associated with the templates that way overrides the encoding that you * specify here. * - * @param parseAsFTL - * If {@code true}, the loaded template is parsed and interpreted normally, as a regular FreeMarker - * template. If {@code false}, the loaded template is treated as a static text, so <code>${...}</code>, - * {@code <#...>} etc. will not have special meaning in it. - * * @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. @@ -2017,7 +2030,7 @@ public class Configuration extends Configurable implements Cloneable, ParserConf * @since 2.3.22 */ public Template getTemplate(String name, Locale locale, Object customLookupCondition, - String encoding, boolean parseAsFTL, boolean ignoreMissing) + String encoding, boolean ignoreMissing) throws TemplateNotFoundException, MalformedTemplateNameException, ParseException, IOException { if (locale == null) { locale = getLocale(); @@ -2026,7 +2039,7 @@ public class Configuration extends Configurable implements Cloneable, ParserConf encoding = getEncoding(locale); } - final GetTemplateResult maybeTemp = templateResolver.getTemplate(name, locale, customLookupCondition, encoding, parseAsFTL); + final GetTemplateResult maybeTemp = templateResolver.getTemplate(name, locale, customLookupCondition, encoding); final Template temp = maybeTemp.getTemplate(); if (temp == null) { if (ignoreMissing) { @@ -2365,7 +2378,7 @@ public class Configuration extends Configurable implements Cloneable, ParserConf */ public void removeTemplateFromCache(String name) throws IOException { Locale loc = getLocale(); - removeTemplateFromCache(name, loc, getEncoding(loc), true); + removeTemplateFromCache(name, loc, getEncoding(loc)); } /** @@ -2373,7 +2386,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), true); + removeTemplateFromCache(name, locale, getEncoding(locale)); } /** @@ -2381,18 +2394,10 @@ public class Configuration extends Configurable implements Cloneable, ParserConf * @since 2.3.19 */ public void removeTemplateFromCache(String name, String encoding) throws IOException { - removeTemplateFromCache(name, getLocale(), encoding, true); + removeTemplateFromCache(name, getLocale(), encoding); } /** - * Equivalent to <tt>removeTemplateFromCache(name, locale, encoding, true)</tt>. - * @since 2.3.19 - */ - public void removeTemplateFromCache(String name, Locale locale, String encoding) throws IOException { - removeTemplateFromCache(name, locale, encoding, true); - } - - /** * Removes a template from the template templateResolver, hence forcing the re-loading * of it when it's next time requested. This is to give the application * finer control over templateResolver updating than {@link #setTemplateUpdateDelayMilliseconds(long)} @@ -2405,10 +2410,8 @@ public class Configuration extends Configurable implements Cloneable, ParserConf * * @since 2.3.19 */ - public void removeTemplateFromCache( - String name, Locale locale, String encoding, boolean parse) - throws IOException { - templateResolver.removeTemplateFromCache(name, locale, encoding, parse); + public void removeTemplateFromCache(String name, Locale locale, String encoding) throws IOException { + templateResolver.removeTemplateFromCache(name, locale, encoding); } /** @@ -2570,6 +2573,14 @@ public class Configuration extends Configurable implements Cloneable, ParserConf } setTemplateUpdateDelayMilliseconds(parsedValue * multipier); + } else if (TEMPLATE_LANGUAGE_KEY_SNAKE_CASE.equals(name) || TEMPLATE_LANGUAGE_KEY_CAMEL_CASE.equals(name)) { + if ("FTL".equals(value)) { + setTemplateLanguage(TemplateLanguage.FTL); + } else if ("static_text".equals(value) || "staticText".equals(value)) { + setTemplateLanguage(TemplateLanguage.STATIC_TEXT); + } else { + throw invalidSettingValueException(name, value); + } } else if (TAG_SYNTAX_KEY_SNAKE_CASE.equals(name) || TAG_SYNTAX_KEY_CAMEL_CASE.equals(name)) { if ("auto_detect".equals(value) || "autoDetect".equals(value)) { setTagSyntax(AUTO_DETECT_TAG_SYNTAX); http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/e365f11b/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 1d1bafc..cac703d 100644 --- a/src/main/java/org/apache/freemarker/core/Environment.java +++ b/src/main/java/org/apache/freemarker/core/Environment.java @@ -2377,12 +2377,12 @@ public final class Environment extends Configurable { } /** - * Same as {@link #getTemplateForInclusion(String, String, boolean, boolean)} with {@code false} + * Same as {@link #getTemplateForInclusion(String, String, boolean)} with {@code false} * {@code ignoreMissing} argument. */ - public Template getTemplateForInclusion(String name, String encoding, boolean parse) + public Template getTemplateForInclusion(String name, String encoding) throws IOException { - return getTemplateForInclusion(name, encoding, parse, false); + return getTemplateForInclusion(name, encoding, false); } /** @@ -2396,7 +2396,7 @@ 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, boolean)} + * {@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 @@ -2404,26 +2404,22 @@ public final class Environment extends Configurable { * using {@code null} is not recommended. In most applications, the value of * {@link Configuration#getEncoding(Locale)} (or {@link Configuration#getDefaultEncoding()}) should be * used here. - * - * @param parseAsFTL - * See identical parameter of {@link Configuration#getTemplate(String, Locale, String, boolean, boolean)} - * + * * @param ignoreMissing - * See identical parameter of {@link Configuration#getTemplate(String, Locale, String, boolean, boolean)} + * See identical parameter of {@link Configuration#getTemplate(String, Locale, String, boolean)} * - * @return Same as {@link Configuration#getTemplate(String, Locale, String, boolean, boolean)} + * @return Same as {@link Configuration#getTemplate(String, Locale, String, boolean)} * @throws IOException * Same as exceptions thrown by - * {@link Configuration#getTemplate(String, Locale, String, boolean, boolean)} + * {@link Configuration#getTemplate(String, Locale, String, boolean)} * * @since 2.3.21 */ - public Template getTemplateForInclusion(String name, String encoding, boolean parseAsFTL, boolean ignoreMissing) + public Template getTemplateForInclusion(String name, String encoding, boolean ignoreMissing) throws IOException { return configuration.getTemplate( name, getLocale(), getIncludedTemplateCustomLookupCondition(), encoding != null ? encoding : getIncludedTemplateEncoding(), - parseAsFTL, ignoreMissing); } @@ -2827,7 +2823,7 @@ public final class Environment extends Configurable { private void initialize() throws IOException, TemplateException { setTemplate(configuration.getTemplate( templateName, locale, customLookupCondition, encoding, - true, false)); + false)); Locale lastLocale = getLocale(); try { setLocale(locale); http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/e365f11b/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 b3a46b7..1270b1c 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 PARSE_PARAMETER = new ParameterRole("\"parse\" parameter"); 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"); http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/e365f11b/src/main/java/org/apache/freemarker/core/ParserConfiguration.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/freemarker/core/ParserConfiguration.java b/src/main/java/org/apache/freemarker/core/ParserConfiguration.java index 50c9bda..d79b545 100644 --- a/src/main/java/org/apache/freemarker/core/ParserConfiguration.java +++ b/src/main/java/org/apache/freemarker/core/ParserConfiguration.java @@ -30,6 +30,8 @@ import org.apache.freemarker.core.outputformat.OutputFormat; */ public interface ParserConfiguration { + TemplateLanguage getTemplateLanguage(); + /** * See {@link Configuration#getTagSyntax()}. */ http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/e365f11b/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 c6328df..23096fe 100644 --- a/src/main/java/org/apache/freemarker/core/Template.java +++ b/src/main/java/org/apache/freemarker/core/Template.java @@ -176,7 +176,7 @@ public class Template extends Configurable { * This is the encoding that we are supposed to be using. At the first glance it's unnecessary because we * already have a {@link Reader} (so decoding with the charset has already happened), however, if this is * non-{@code null} and there's an {@code #ftl} header with {@code encoding} parameter, they must match, - * or else a {@link WrongEncodingException} is thrown. Thus, it should be set if to decode the template, + * or else a {@link WrongTemplateCharsetException} is thrown. Thus, it should be set if to decode the template, * we were using an encoding (a charset), otherwise it should be {@code null}. It's also kept as * meta-info (returned by {@link #getEncoding()}). It also has an impact when {@code #include}-ing or * {@code #import}-ing another template from this template, as its default encoding will be this. But @@ -224,16 +224,16 @@ public class Template extends Configurable { * * @param streamToUnmarkWhenEncEstabd * If not {@code null}, when during the parsing we reach a point where we know that no {@link - * WrongEncodingException} will be thrown, {@link InputStream#mark(int) mark(0)} will be called on this. + * WrongTemplateCharsetException} will be thrown, {@link InputStream#mark(int) mark(0)} will be called on this. * This is meant to be used when the reader parameter is a {@link InputStreamReader}, and this parameter is * the underlying {@link InputStream}, and you have a mark at the beginning of the {@link InputStream} so - * that you can retry if a {@link WrongEncodingException} is thrown without extra I/O. As keeping that + * that you can retry if a {@link WrongTemplateCharsetException} is thrown without extra I/O. As keeping that * mark consumes some resources, so you may want to release it as soon as possible. */ public Template( String name, String sourceName, Reader reader, Configuration cfg, ParserConfiguration customParserConfiguration, - String encoding, InputStream streamToUnmarkWhenEncEstabd) throws IOException { + String encoding, InputStream streamToUnmarkWhenEncEstabd) throws IOException, ParseException { this(name, sourceName, cfg, customParserConfiguration); setEncoding(encoding); @@ -585,7 +585,7 @@ 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, boolean)} for + * parameter of {@link Configuration#getTemplate(String, java.util.Locale, Object, String, boolean)} for * more explanation. * * @since 2.3.22 @@ -931,57 +931,5 @@ public class Template extends Configurable { return prefix + ":" + localName; } - /** - * Thrown by the {@link Template} constructors that specify a non-{@code null} encoding whoch doesn't match the - * encoding specified in the {@code #ftl} header of the template. - */ - static public class WrongEncodingException extends ParseException { - private static final long serialVersionUID = 1L; - - /** @deprecated Use {@link #getTemplateSpecifiedEncoding()} instead. */ - @Deprecated - public String templateSpecifiedEncoding; - - private final String constructorSpecifiedEncoding; - - /** - * @deprecated Use {@link #WrongEncodingException(String, String)}. - */ - @Deprecated - public WrongEncodingException(String templateSpecifiedEncoding) { - this(templateSpecifiedEncoding, null); - } - - /** - * @since 2.3.22 - */ - public WrongEncodingException(String templateSpecifiedEncoding, String constructorSpecifiedEncoding) { - this.templateSpecifiedEncoding = templateSpecifiedEncoding; - this.constructorSpecifiedEncoding = constructorSpecifiedEncoding; - } - - @Override - public String getMessage() { - return "Encoding specified inside the template (" + templateSpecifiedEncoding - + ") doesn't match the encoding specified for the Template constructor" - + (constructorSpecifiedEncoding != null ? " (" + constructorSpecifiedEncoding + ")." : "."); - } - - /** - * @since 2.3.22 - */ - public String getTemplateSpecifiedEncoding() { - return templateSpecifiedEncoding; - } - - /** - * @since 2.3.22 - */ - public String getConstructorSpecifiedEncoding() { - return constructorSpecifiedEncoding; - } - - } - } http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/e365f11b/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 28023ea..2e8c0f6 100644 --- a/src/main/java/org/apache/freemarker/core/TemplateConfiguration.java +++ b/src/main/java/org/apache/freemarker/core/TemplateConfiguration.java @@ -79,6 +79,7 @@ import org.apache.freemarker.core.valueformat.TemplateNumberFormatFactory; */ public final class TemplateConfiguration extends Configurable implements ParserConfiguration { + private TemplateLanguage templateLanguage; private Integer tagSyntax; private Integer namingConvention; private Boolean whitespaceStripping; @@ -224,6 +225,9 @@ public final class TemplateConfiguration extends Configurable implements ParserC if (tc.isTagSyntaxSet()) { setTagSyntax(tc.getTagSyntax()); } + if (tc.isTemplateLanguageSet()) { + setTemplateLanguage(tc.getTemplateLanguage()); + } if (tc.isTemplateExceptionHandlerSet()) { setTemplateExceptionHandler(tc.getTemplateExceptionHandler()); } @@ -373,7 +377,7 @@ public final class TemplateConfiguration extends Configurable implements ParserC */ public void setTagSyntax(int tagSyntax) { Configuration.valideTagSyntaxValue(tagSyntax); - this.tagSyntax = Integer.valueOf(tagSyntax); + this.tagSyntax = tagSyntax; } /** @@ -381,7 +385,7 @@ public final class TemplateConfiguration extends Configurable implements ParserC */ @Override public int getTagSyntax() { - return tagSyntax != null ? tagSyntax.intValue() : getNonNullParentConfiguration().getTagSyntax(); + return tagSyntax != null ? tagSyntax : getNonNullParentConfiguration().getTagSyntax(); } /** @@ -392,11 +396,31 @@ public final class TemplateConfiguration extends Configurable implements ParserC } /** + * See {@link Configuration#getTemplateLanguage()} + */ + @Override + public TemplateLanguage getTemplateLanguage() { + return templateLanguage != null ? templateLanguage : getNonNullParentConfiguration().getTemplateLanguage(); + } + + /** + * See {@link Configuration#setTemplateLanguage(TemplateLanguage)} + */ + public void setTemplateLanguage(TemplateLanguage templateLanguage) { + _NullArgumentException.check("templateLanguage", templateLanguage); + this.templateLanguage = templateLanguage; + } + + public boolean isTemplateLanguageSet() { + return templateLanguage != null; + } + + /** * See {@link Configuration#setNamingConvention(int)}. */ public void setNamingConvention(int namingConvention) { Configuration.validateNamingConventionValue(namingConvention); - this.namingConvention = Integer.valueOf(namingConvention); + this.namingConvention = namingConvention; } /** @@ -404,7 +428,7 @@ public final class TemplateConfiguration extends Configurable implements ParserC */ @Override public int getNamingConvention() { - return namingConvention != null ? namingConvention.intValue() + return namingConvention != null ? namingConvention : getNonNullParentConfiguration().getNamingConvention(); } http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/e365f11b/src/main/java/org/apache/freemarker/core/TemplateLanguage.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/freemarker/core/TemplateLanguage.java b/src/main/java/org/apache/freemarker/core/TemplateLanguage.java new file mode 100644 index 0000000..37abf56 --- /dev/null +++ b/src/main/java/org/apache/freemarker/core/TemplateLanguage.java @@ -0,0 +1,103 @@ +/* + * 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 java.io.IOException; +import java.io.InputStream; +import java.io.Reader; + +import org.apache.freemarker.core.util._StringUtil; + +/** + * Represents a template language. Currently this class is not mature, so it can't be implemented outside FreeMarker, + * also its methods shouldn't be called from outside FreeMarker. + */ +// [FM3] Make this mature, or hide its somehow. Actually, parse can't be hidden because custom TemplateResolver-s need +// to call it. +public abstract class TemplateLanguage { + + // FIXME [FM3] If we leave this here, FTL will be a required dependency of core (which is not nice if + // template languages will be pluggable). + public static final TemplateLanguage FTL = new TemplateLanguage("FreeMarker Template Language") { + @Override + public boolean getCanSpecifyCharsetInContent() { + return true; + } + + @Override + public Template parse(String name, String sourceName, Reader reader, Configuration cfg, ParserConfiguration customParserConfiguration, String encoding, InputStream streamToUnmarkWhenEncEstabd) throws IOException, ParseException { + return new Template(name, sourceName, reader, cfg, customParserConfiguration, + encoding, streamToUnmarkWhenEncEstabd); + } + }; + + public static final TemplateLanguage STATIC_TEXT = new TemplateLanguage("Static text") { + @Override + public boolean getCanSpecifyCharsetInContent() { + return false; + } + + @Override + public Template parse(String name, String sourceName, Reader reader, Configuration cfg, ParserConfiguration customParserConfiguration, String encoding, InputStream streamToUnmarkWhenEncEstabd) throws IOException, ParseException { + // Read the contents into a StringWriter, then construct a single-text-block template from it. + final StringBuilder sb = new StringBuilder(); + final char[] buf = new char[4096]; + int charsRead; + while ((charsRead = reader.read(buf)) > 0) { + sb.append(buf, 0, charsRead); + } + return Template.createPlainTextTemplate(name, sourceName, sb.toString(), cfg, + encoding); + } + }; + + private final String name; + + // Package visibility to prevent user implementations until this API is mature. + TemplateLanguage(String name) { + this.name = name; + } + + /** + * Returns if the template can specify its own charset inside the template. If so, {@link #parse(String, String, + * Reader, Configuration, ParserConfiguration, String, InputStream)} can throw + * {@link WrongTemplateCharsetException}, and it might gets a non-{@code null} for the {@link InputStream} + * parameter. + */ + public abstract boolean getCanSpecifyCharsetInContent(); + + /** + * See {@link Template#Template(String, String, Reader, Configuration, ParserConfiguration, String, InputStream)}. + */ + public abstract Template parse(String name, String sourceName, Reader reader, + Configuration cfg, ParserConfiguration customParserConfiguration, + String encoding, InputStream streamToUnmarkWhenEncEstabd) + throws IOException, ParseException; + + public String getName() { + return name; + } + + @Override + public final String toString() { + return "TemplateLanguage(" + _StringUtil.jQuote(name) + ")"; + } + +} http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/e365f11b/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 7f819e7..fced93f 100644 --- a/src/main/java/org/apache/freemarker/core/TemplateNotFoundException.java +++ b/src/main/java/org/apache/freemarker/core/TemplateNotFoundException.java @@ -54,7 +54,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, boolean)}. + * {@link Configuration#getTemplate(String, java.util.Locale, Object, String, boolean)}. */ public Object getCustomLookupCondition() { return customLookupCondition; http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/e365f11b/src/main/java/org/apache/freemarker/core/WrongTemplateCharsetException.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/freemarker/core/WrongTemplateCharsetException.java b/src/main/java/org/apache/freemarker/core/WrongTemplateCharsetException.java new file mode 100644 index 0000000..18d3ed4 --- /dev/null +++ b/src/main/java/org/apache/freemarker/core/WrongTemplateCharsetException.java @@ -0,0 +1,61 @@ +/* + * 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; + +/** + * Thrown by the {@link Template} constructors that specify a non-{@code null} encoding whoch doesn't match the + * encoding specified in the {@code #ftl} header of the template. + */ +public class WrongTemplateCharsetException extends ParseException { + private static final long serialVersionUID = 1L; + + private final String templateSpecifiedEncoding; + private final String constructorSpecifiedEncoding; + + /** + * @since 2.3.22 + */ + public WrongTemplateCharsetException(String templateSpecifiedEncoding, String constructorSpecifiedEncoding) { + this.templateSpecifiedEncoding = templateSpecifiedEncoding; + this.constructorSpecifiedEncoding = constructorSpecifiedEncoding; + } + + @Override + public String getMessage() { + return "Encoding specified inside the template (" + templateSpecifiedEncoding + + ") doesn't match the encoding specified for the Template constructor" + + (constructorSpecifiedEncoding != null ? " (" + constructorSpecifiedEncoding + ")." : "."); + } + + /** + * @since 2.3.22 + */ + public String getTemplateSpecifiedEncoding() { + return templateSpecifiedEncoding; + } + + /** + * @since 2.3.22 + */ + public String getConstructorSpecifiedEncoding() { + return constructorSpecifiedEncoding; + } + +} http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/e365f11b/src/main/java/org/apache/freemarker/core/_ParserConfigurationWithInheritedFormat.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/freemarker/core/_ParserConfigurationWithInheritedFormat.java b/src/main/java/org/apache/freemarker/core/_ParserConfigurationWithInheritedFormat.java index b2033ea..53d09ea 100644 --- a/src/main/java/org/apache/freemarker/core/_ParserConfigurationWithInheritedFormat.java +++ b/src/main/java/org/apache/freemarker/core/_ParserConfigurationWithInheritedFormat.java @@ -48,6 +48,11 @@ public final class _ParserConfigurationWithInheritedFormat implements ParserConf } @Override + public TemplateLanguage getTemplateLanguage() { + return wrappedPCfg.getTemplateLanguage(); + } + + @Override public OutputFormat getOutputFormat() { return outputFormat != null ? outputFormat : wrappedPCfg.getOutputFormat(); } http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/e365f11b/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 3e90489..2260267 100644 --- a/src/main/java/org/apache/freemarker/core/templateresolver/GetTemplateResult.java +++ b/src/main/java/org/apache/freemarker/core/templateresolver/GetTemplateResult.java @@ -23,7 +23,7 @@ import java.util.Locale; import org.apache.freemarker.core.Template; /** - * Used for the return value of {@link TemplateResolver#getTemplate(String, Locale, Object, String, boolean)}. + * Used for the return value of {@link TemplateResolver#getTemplate(String, Locale, Object, String)}. * * @since 3.0.0 */ http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/e365f11b/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 e5372a4..7d6f7a6 100644 --- a/src/main/java/org/apache/freemarker/core/templateresolver/TemplateLoaderSession.java +++ b/src/main/java/org/apache/freemarker/core/templateresolver/TemplateLoaderSession.java @@ -28,7 +28,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, boolean)} call is executed inside a single + * {@link DefaultTemplateResolver#getTemplate(String, java.util.Locale, Object, String)} 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/e365f11b/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 fbe7d82..3db956c 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, boolean)}; see requirements there, such + * {@link Configuration#getTemplate(String, Locale, Object, String, 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/e365f11b/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 3835e72..1b04ba7 100644 --- a/src/main/java/org/apache/freemarker/core/templateresolver/TemplateResolver.java +++ b/src/main/java/org/apache/freemarker/core/templateresolver/TemplateResolver.java @@ -81,9 +81,9 @@ public abstract class TemplateResolver { * should never be a {@link TemplateNotFoundException}, as that condition is indicated in the return * value. */ - // [FM3] These parameters will certainly be removed: String suggestedEncoding, boolean parseAsFTL + // [FM3] This parameters will be removed: String encoding public abstract GetTemplateResult getTemplate(String name, Locale locale, Object customLookupCondition, - String encoding, boolean parseAsFTL) + String encoding) 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, boolean)} + * For the meaning of the parameters, see {@link #getTemplate(String, Locale, Object, String)} * * <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, boolean parse) + public abstract void removeTemplateFromCache(String name, Locale locale, String encoding) throws IOException, UnsupportedOperationException; /** http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/e365f11b/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 2bef4cd..14d04f7 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 @@ -34,7 +34,9 @@ import java.util.StringTokenizer; import org.apache.freemarker.core.Configuration; import org.apache.freemarker.core.Template; import org.apache.freemarker.core.TemplateConfiguration; +import org.apache.freemarker.core.TemplateLanguage; import org.apache.freemarker.core.TemplateNotFoundException; +import org.apache.freemarker.core.WrongTemplateCharsetException; import org.apache.freemarker.core._CoreLogs; import org.apache.freemarker.core.templateresolver.CacheStorage; import org.apache.freemarker.core.templateresolver.GetTemplateResult; @@ -222,7 +224,7 @@ public class DefaultTemplateResolver extends TemplateResolver { */ @Override public GetTemplateResult getTemplate(String name, Locale locale, Object customLookupCondition, - String encoding, boolean parseAsFTL) + String encoding) throws IOException { _NullArgumentException.check("name", name); _NullArgumentException.check("locale", locale); @@ -234,7 +236,7 @@ public class DefaultTemplateResolver extends TemplateResolver { return new GetTemplateResult(name, "The TemplateLoader (and TemplateLoader2) was null."); } - Template template = getTemplateInternal(name, locale, customLookupCondition, encoding, parseAsFTL); + Template template = getTemplateInternal(name, locale, customLookupCondition, encoding); return template != null ? new GetTemplateResult(template) : new GetTemplateResult(name, (String) null); } @@ -250,13 +252,13 @@ public class DefaultTemplateResolver extends TemplateResolver { private Template getTemplateInternal( final String name, final Locale locale, final Object customLookupCondition, - final String encoding, final boolean parseAsFTL) + final String encoding) throws IOException { final boolean debug = LOG.isDebugEnabled(); final String debugPrefix = debug - ? getDebugPrefix("getTemplate", name, locale, customLookupCondition, encoding, parseAsFTL) + ? getDebugPrefix("getTemplate", name, locale, customLookupCondition, encoding) : null; - final CachedResultKey cacheKey = new CachedResultKey(name, locale, customLookupCondition, encoding, parseAsFTL); + final CachedResultKey cacheKey = new CachedResultKey(name, locale, customLookupCondition, encoding); CachedResult oldCachedResult = (CachedResult) cacheStorage.get(cacheKey); @@ -386,7 +388,7 @@ public class DefaultTemplateResolver extends TemplateResolver { Template template = loadTemplate( templateLoaderResult, name, newLookupResult.getTemplateSourceName(), locale, customLookupCondition, - encoding, parseAsFTL); + encoding); if (session != null) { session.close(); if (debug) { @@ -523,7 +525,7 @@ public class DefaultTemplateResolver extends TemplateResolver { private Template loadTemplate( TemplateLoadingResult templateLoaderResult, final String name, final String sourceName, Locale locale, final Object customLookupCondition, - String initialEncoding, final boolean parseAsFTL) throws IOException { + String initialEncoding) throws IOException { TemplateConfiguration tc; { TemplateConfiguration cfgTC; @@ -549,7 +551,8 @@ public class DefaultTemplateResolver extends TemplateResolver { tc = cfgTC; } } - + + TemplateLanguage templateLanguage = null; if (tc != null) { // TC.{encoding,locale} is stronger than the cfg.getTemplate arguments by design. if (tc.isEncodingSet()) { @@ -558,8 +561,15 @@ public class DefaultTemplateResolver extends TemplateResolver { if (tc.isLocaleSet()) { locale = tc.getLocale(); } + if (tc.isTemplateLanguageSet()) { + templateLanguage = tc.getTemplateLanguage(); + } } - + + if (templateLanguage == null) { + templateLanguage = config.getTemplateLanguage(); + } + Template template; { Reader reader = templateLoaderResult.getReader(); @@ -573,7 +583,7 @@ public class DefaultTemplateResolver extends TemplateResolver { initialEncoding = null; // No charset decoding has happened markedInputStream = null; } else if (inputStream != null) { - if (parseAsFTL) { + if (templateLanguage.getCanSpecifyCharsetInContent()) { // We need mark support, to restart if the charset suggested by <#ftl encoding=...> differs // from that we use initially. if (!inputStream.markSupported()) { @@ -594,37 +604,27 @@ public class DefaultTemplateResolver extends TemplateResolver { } try { - if (parseAsFTL) { - try { - template = new Template(name, sourceName, reader, config, tc, - initialEncoding, markedInputStream); - } catch (Template.WrongEncodingException wee) { - final String templateSpecifiedEncoding = wee.getTemplateSpecifiedEncoding(); - - if (inputStream != null) { - // We restart InputStream to re-decode it with the new charset. - inputStream.reset(); - - // Don't close `reader`; it's an InputStreamReader that would close the wrapped InputStream. - reader = new InputStreamReader(inputStream, templateSpecifiedEncoding); - } else { - // Should be impossible to get here - throw new BugException(); - } - - template = new Template(name, sourceName, reader, config, tc, - templateSpecifiedEncoding, markedInputStream); + try { + template = templateLanguage.parse(name, sourceName, reader, config, tc, + initialEncoding, markedInputStream); + } catch (WrongTemplateCharsetException charsetException) { + final String templateSpecifiedEncoding = charsetException.getTemplateSpecifiedEncoding(); + + if (inputStream != null) { + // We restart InputStream to re-decode it with the new charset. + inputStream.reset(); + + // Don't close `reader`; it's an InputStreamReader that would close the wrapped InputStream. + reader = new InputStreamReader(inputStream, templateSpecifiedEncoding); + } else { + throw new IllegalStateException( + "TemplateLanguage " + _StringUtil.jQuote(templateLanguage.getName()) + " has thrown " + + WrongTemplateCharsetException.class.getName() + + ", but its canSpecifyCharsetInContent property is false."); } - } else { - // Read the contents into a StringWriter, then construct a single-text-block template from it. - final StringBuilder sb = new StringBuilder(); - final char[] buf = new char[4096]; - int charsRead; - while ((charsRead = reader.read(buf)) > 0) { - sb.append(buf, 0, charsRead); - } - template = Template.createPlainTextTemplate(name, sourceName, sb.toString(), config, - initialEncoding); + + template = templateLanguage.parse(name, sourceName, reader, config, tc, + templateSpecifiedEncoding, markedInputStream); } } finally { reader.close(); @@ -689,7 +689,7 @@ public class DefaultTemplateResolver extends TemplateResolver { /** * Removes all entries from the cache, forcing reloading of templates on subsequent - * {@link #getTemplate(String, Locale, Object, String, boolean)} calls. + * {@link #getTemplate(String, Locale, Object, String)} calls. * * @param resetTemplateLoader * Whether to call {@link TemplateLoader#resetState()}. on the template loader. @@ -717,13 +717,13 @@ public class DefaultTemplateResolver extends TemplateResolver { } /** - * Same as {@link #removeTemplateFromCache(String, Locale, Object, String, boolean)} with {@code null} + * Same as {@link #removeTemplateFromCache(String, Locale, Object, String)} with {@code null} * {@code customLookupCondition}. */ @Override public void removeTemplateFromCache( - String name, Locale locale, String encoding, boolean parse) throws IOException { - removeTemplateFromCache(name, locale, null, encoding, parse); + String name, Locale locale, String encoding) throws IOException { + removeTemplateFromCache(name, locale, null, encoding); } /** @@ -732,10 +732,10 @@ public class DefaultTemplateResolver extends TemplateResolver { * {@link #setTemplateUpdateDelayMilliseconds(long)} alone does. * * For the meaning of the parameters, see - * {@link Configuration#getTemplate(String, Locale, Object, String, boolean, boolean)} + * {@link Configuration#getTemplate(String, Locale, Object, String, boolean)} */ public void removeTemplateFromCache( - String name, Locale locale, Object customLookupCondition, String encoding, boolean parse) + String name, Locale locale, Object customLookupCondition, String encoding) throws IOException { if (name == null) { throw new IllegalArgumentException("Argument \"name\" can't be null"); @@ -750,9 +750,9 @@ public class DefaultTemplateResolver extends TemplateResolver { if (name != null && templateLoader != null) { boolean debug = LOG.isDebugEnabled(); String debugPrefix = debug - ? getDebugPrefix("removeTemplate", name, locale, customLookupCondition, encoding, parse) + ? getDebugPrefix("removeTemplate", name, locale, customLookupCondition, encoding) : null; - CachedResultKey tk = new CachedResultKey(name, locale, customLookupCondition, encoding, parse); + CachedResultKey tk = new CachedResultKey(name, locale, customLookupCondition, encoding); cacheStorage.remove(tk); if (debug) { @@ -761,14 +761,12 @@ public class DefaultTemplateResolver extends TemplateResolver { } } - private String getDebugPrefix(String operation, String name, Locale locale, Object customLookupCondition, String encoding, - boolean parse) { + private String getDebugPrefix(String operation, String name, Locale locale, Object customLookupCondition, String encoding) { return operation + " " + _StringUtil.jQuoteNoXSS(name) + "(" + _StringUtil.jQuoteNoXSS(locale) + (customLookupCondition != null ? ", cond=" + _StringUtil.jQuoteNoXSS(customLookupCondition) : "") + ", " + encoding - + (parse ? ", parsed)" : ", unparsed]") - + ": "; + + "): "; } /** @@ -817,14 +815,12 @@ public class DefaultTemplateResolver extends TemplateResolver { private final Locale locale; private final Object customLookupCondition; private final String encoding; - private final boolean parse; - CachedResultKey(String name, Locale locale, Object customLookupCondition, String encoding, boolean parse) { + CachedResultKey(String name, Locale locale, Object customLookupCondition, String encoding) { this.name = name; this.locale = locale; this.customLookupCondition = customLookupCondition; this.encoding = encoding; - this.parse = parse; } @Override @@ -832,7 +828,6 @@ public class DefaultTemplateResolver extends TemplateResolver { if (o instanceof CachedResultKey) { CachedResultKey tk = (CachedResultKey) o; return - parse == tk.parse && name.equals(tk.name) && locale.equals(tk.locale) && nullSafeEquals(customLookupCondition, tk.customLookupCondition) && @@ -847,13 +842,12 @@ public class DefaultTemplateResolver extends TemplateResolver { name.hashCode() ^ locale.hashCode() ^ encoding.hashCode() ^ - (customLookupCondition != null ? customLookupCondition.hashCode() : 0) ^ - Boolean.valueOf(!parse).hashCode(); + (customLookupCondition != null ? customLookupCondition.hashCode() : 0); } } /** - * Hold the a cached {@link #getTemplate(String, Locale, Object, String, boolean)} result and the associated + * Hold the a cached {@link #getTemplate(String, Locale, Object, String)} 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/e365f11b/src/main/javacc/FTL.jj ---------------------------------------------------------------------- diff --git a/src/main/javacc/FTL.jj b/src/main/javacc/FTL.jj index fd3f429..2566df6 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, parseExp = null, encodingExp = null, ignoreMissingExp = null; + ASTExpression exp, encodingExp = null, ignoreMissingExp = null; } { start = <_INCLUDE> @@ -2947,9 +2947,7 @@ ASTDirInclude Include() : exp = ASTExpression() { String attString = att.image; - if (attString.equalsIgnoreCase("parse")) { - parseExp = exp; - } else if (attString.equalsIgnoreCase("encoding")) { + if (attString.equalsIgnoreCase("encoding")) { encodingExp = exp; } else if (attString.equalsIgnoreCase("ignore_missing") || attString.equals("ignoreMissing")) { token_source.checkNamingConvention(att); @@ -2958,7 +2956,7 @@ ASTDirInclude Include() : String correctedName = attString.equals("ignoreMissing") ? "ignore_missing" : null; throw new ParseException( "Unsupported named #include parameter: \"" + attString + "\". Supported parameters are: " - + "\"parse\", \"encoding\", \"ignore_missing\"." + + "\"encoding\", \"ignore_missing\"." + (correctedName == null ? "" : " Supporting camelCase parameter names is planned for FreeMarker 2.4.0; " @@ -2970,7 +2968,7 @@ ASTDirInclude Include() : )* end = LooseDirectiveEnd() { - ASTDirInclude result = new ASTDirInclude(template, nameExp, encodingExp, parseExp, ignoreMissingExp); + ASTDirInclude result = new ASTDirInclude(template, nameExp, encodingExp, ignoreMissingExp); result.setLocation(template, start, end); return result; } @@ -3897,9 +3895,9 @@ void HeaderElement() : } if (template.getEncoding() != null && vs != null && !template.getEncoding().equalsIgnoreCase(vs)) { - throw new Template.WrongEncodingException(vs, template.getEncoding()); + throw new WrongTemplateCharsetException(vs, template.getEncoding()); } - // There will be no WrongEncodingException exception, release mark buffer: + // There will be no WrongTemplateCharsetException exception, release mark buffer: if (streamToUnmarkWhenEncEstabd != null) { streamToUnmarkWhenEncEstabd.mark(0); streamToUnmarkWhenEncEstabd = null; http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/e365f11b/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 e15d2b5..6c7a5fb 100644 --- a/src/manual/en_US/FM3-CHANGE-LOG.txt +++ b/src/manual/en_US/FM3-CHANGE-LOG.txt @@ -156,4 +156,9 @@ 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.n \ No newline at end of file +- DefaultObjectWrapper is not 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 http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/e365f11b/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 6ae7396..51cdcc3 100644 --- a/src/test/java/org/apache/freemarker/core/ConfigurationTest.java +++ b/src/test/java/org/apache/freemarker/core/ConfigurationTest.java @@ -390,15 +390,6 @@ public class ConfigurationTest extends TestCase { // 4 args: { - Template t = cfg.getTemplate(tFtl, hu, utf8, false); - 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, utf8, true); assertEquals(tFtl, t.getName()); assertEquals(tFtl, t.getSourceName()); @@ -425,55 +416,19 @@ public class ConfigurationTest extends TestCase { assertEquals(latin2, t.getEncoding()); assertOutputEquals("1", t); } - - // 5 args: - { - Template t = cfg.getTemplate(tFtl, hu, utf8, false, 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, hu, utf8, true, false); - 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, false); - 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, false); - assertEquals(tFtl, t.getName()); - assertEquals(tFtl, t.getSourceName()); - assertEquals(hu, t.getLocale()); - assertNull(t.getCustomLookupCondition()); - assertEquals(latin2, t.getEncoding()); - assertOutputEquals("1", t); - } + + // Ignore missing try { - cfg.getTemplate("missing.ftl", hu, utf8, true, false); + cfg.getTemplate("missing.ftl", hu, utf8, false); fail(); } catch (TemplateNotFoundException e) { // Expected } - assertNull(cfg.getTemplate("missing.ftl", hu, utf8, true, true)); + assertNull(cfg.getTemplate("missing.ftl", hu, utf8, true)); - // 6 args: + // 5 args: { - Template t = cfg.getTemplate(tFtl, hu, custLookupCond, utf8, true, false); + Template t = cfg.getTemplate(tFtl, hu, custLookupCond, utf8, false); assertEquals(tFtl, t.getName()); assertEquals(tFtl, t.getSourceName()); assertEquals(hu, t.getLocale()); @@ -482,16 +437,7 @@ public class ConfigurationTest extends TestCase { assertOutputEquals("1", t); } { - Template t = cfg.getTemplate(tFtl, hu, custLookupCond, utf8, false, false); - assertEquals(tFtl, t.getName()); - assertEquals(tFtl, t.getSourceName()); - assertEquals(hu, t.getLocale()); - assertEquals(custLookupCond, t.getCustomLookupCondition()); - assertEquals(utf8, t.getEncoding()); - assertOutputEquals("${1}", t); - } - { - Template t = cfg.getTemplate(tFtl, null, custLookupCond, utf8, true, false); + Template t = cfg.getTemplate(tFtl, null, custLookupCond, utf8, false); assertEquals(tFtl, t.getName()); assertEquals(tFtl, t.getSourceName()); assertEquals(Locale.GERMAN, t.getLocale()); @@ -500,7 +446,7 @@ public class ConfigurationTest extends TestCase { assertOutputEquals("1", t); } { - Template t = cfg.getTemplate(tFtl, hu, custLookupCond, null, true, false); + Template t = cfg.getTemplate(tFtl, hu, custLookupCond, null, false); assertEquals(tFtl, t.getName()); assertEquals(tFtl, t.getSourceName()); assertEquals(hu, t.getLocale()); @@ -509,12 +455,12 @@ public class ConfigurationTest extends TestCase { assertOutputEquals("1", t); } try { - cfg.getTemplate("missing.ftl", hu, custLookupCond, utf8, true, false); + cfg.getTemplate("missing.ftl", hu, custLookupCond, utf8, false); fail(); } catch (TemplateNotFoundException e) { // Expected } - assertNull(cfg.getTemplate("missing.ftl", hu, custLookupCond, utf8, true, true)); + 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/e365f11b/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 index 5f6ce53..60ba865 100644 --- a/src/test/java/org/apache/freemarker/core/TemplatGetEncodingTest.java +++ b/src/test/java/org/apache/freemarker/core/TemplatGetEncodingTest.java @@ -23,6 +23,8 @@ 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; @@ -36,7 +38,11 @@ public class TemplatGetEncodingTest { cfg.setDefaultEncoding("ISO-8859-2"); ByteArrayTemplateLoader tl = new ByteArrayTemplateLoader(); tl.putTemplate("t", "test".getBytes(StandardCharsets.UTF_8)); - tl.putTemplate("tnp", "<#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()); } @@ -57,13 +63,13 @@ public class TemplatGetEncodingTest { } { - Template tDefEnc = cfg.getTemplate("tnp", null, null, false); + Template tDefEnc = cfg.getTemplate("static", null, null, false); assertEquals("ISO-8859-2", tDefEnc.getEncoding()); - assertSame(tDefEnc, cfg.getTemplate("tnp", null, null, false)); + assertSame(tDefEnc, cfg.getTemplate("static", null, null, false)); - Template tUTF8 = cfg.getTemplate("tnp", null, "UTF-8", false); + Template tUTF8 = cfg.getTemplate("static", null, "UTF-8", false); assertEquals("UTF-8", tUTF8.getEncoding()); - assertSame(tUTF8, cfg.getTemplate("tnp", null, "UTF-8", false)); + assertSame(tUTF8, cfg.getTemplate("static", null, "UTF-8", false)); assertNotSame(tDefEnc, tUTF8); } http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/e365f11b/src/test/java/org/apache/freemarker/core/TemplateConfigurationTest.java ---------------------------------------------------------------------- diff --git a/src/test/java/org/apache/freemarker/core/TemplateConfigurationTest.java b/src/test/java/org/apache/freemarker/core/TemplateConfigurationTest.java index 7943a2d..2690905 100644 --- a/src/test/java/org/apache/freemarker/core/TemplateConfigurationTest.java +++ b/src/test/java/org/apache/freemarker/core/TemplateConfigurationTest.java @@ -48,6 +48,8 @@ import org.apache.freemarker.core.model.impl.RestrictedObjectWrapper; import org.apache.freemarker.core.outputformat.impl.HTMLOutputFormat; import org.apache.freemarker.core.outputformat.impl.UndefinedOutputFormat; import org.apache.freemarker.core.outputformat.impl.XMLOutputFormat; +import org.apache.freemarker.core.templateresolver.ConditionalTemplateConfigurationFactory; +import org.apache.freemarker.core.templateresolver.FileExtensionMatcher; import org.apache.freemarker.core.templateresolver.impl.StringTemplateLoader; import org.apache.freemarker.core.userpkg.BaseNTemplateNumberFormatFactory; import org.apache.freemarker.core.userpkg.EpochMillisDivTemplateDateFormatFactory; @@ -185,6 +187,7 @@ public class TemplateConfigurationTest { ImmutableMap.of("dummy", EpochMillisTemplateDateFormatFactory.INSTANCE)); // Parser-only settings: + SETTING_ASSIGNMENTS.put("templateLanguage", TemplateLanguage.STATIC_TEXT); SETTING_ASSIGNMENTS.put("tagSyntax", Configuration.SQUARE_BRACKET_TAG_SYNTAX); SETTING_ASSIGNMENTS.put("namingConvention", Configuration.LEGACY_NAMING_CONVENTION); SETTING_ASSIGNMENTS.put("whitespaceStripping", false); @@ -677,7 +680,37 @@ public class TemplateConfigurationTest { "13", "8"); testedProps.add(Configuration.TAB_SIZE_KEY_CAMEL_CASE); } - + + { + // As the TemplateLanguage-based parser selection happens in the TemplateResolver, we can't use + // assertOutput here, as that hard-coded to create an FTL Template. + + TemplateConfiguration tc = new TemplateConfiguration(); + tc.setTemplateLanguage(TemplateLanguage.STATIC_TEXT); + + Configuration cfg = new Configuration(Configuration.VERSION_3_0_0); + cfg.setTemplateConfigurations(new ConditionalTemplateConfigurationFactory(new FileExtensionMatcher + ("txt"), tc)); + + StringTemplateLoader templateLoader = new StringTemplateLoader(); + templateLoader.putTemplate("adhoc.ftl", "${1+1}"); + templateLoader.putTemplate("adhoc.txt", "${1+1}"); + cfg.setTemplateLoader(templateLoader); + + { + StringWriter out = new StringWriter(); + cfg.getTemplate("adhoc.ftl").process(null, out); + assertEquals("2", out.toString()); + } + { + StringWriter out = new StringWriter(); + cfg.getTemplate("adhoc.txt").process(null, out); + assertEquals("${1+1}", out.toString()); + } + + testedProps.add(Configuration.TEMPLATE_LANGUAGE_KEY_CAMEL_CASE); + } + assertEquals("Check that you have tested all parser settings; ", PARSER_PROP_NAMES, testedProps); } http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/e365f11b/src/test/java/org/apache/freemarker/core/TemplateConstructorsTest.java ---------------------------------------------------------------------- diff --git a/src/test/java/org/apache/freemarker/core/TemplateConstructorsTest.java b/src/test/java/org/apache/freemarker/core/TemplateConstructorsTest.java index ed2dbeb..cec01d7 100644 --- a/src/test/java/org/apache/freemarker/core/TemplateConstructorsTest.java +++ b/src/test/java/org/apache/freemarker/core/TemplateConstructorsTest.java @@ -87,7 +87,7 @@ public class TemplateConstructorsTest { try { new Template(name, sourceName, createReaderForceUTF8(), cfg, encoding); fail(); - } catch (Template.WrongEncodingException e) { + } catch (WrongTemplateCharsetException e) { assertThat(e.getMessage(), containsString("utf-8")); assertThat(e.getMessage(), containsString(encoding)); }
