http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/7d61a45d/src/main/java/org/apache/freemarker/core/templateresolver/impl/URLTemplateLoader.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/freemarker/core/templateresolver/impl/URLTemplateLoader.java b/src/main/java/org/apache/freemarker/core/templateresolver/impl/URLTemplateLoader.java index 8f348de..dcb9222 100644 --- a/src/main/java/org/apache/freemarker/core/templateresolver/impl/URLTemplateLoader.java +++ b/src/main/java/org/apache/freemarker/core/templateresolver/impl/URLTemplateLoader.java @@ -61,7 +61,7 @@ public abstract class URLTemplateLoader implements TemplateLoader { /** * Sets if {@link URLConnection#setUseCaches(boolean)} will be called, and with what value. By default this is * {@code false}, because FreeMarker has its own template cache with its own update delay setting - * ({@link Configuration#setTemplateUpdateDelayMilliseconds(long)}). If this is set to {@code null}, + * ({@link Configuration#getTemplateUpdateDelayMilliseconds()}). If this is set to {@code null}, * {@link URLConnection#setUseCaches(boolean)} won't be called. */ public void setURLConnectionUsesCaches(Boolean urlConnectionUsesCaches) {
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/7d61a45d/src/main/java/org/apache/freemarker/core/util/CommonBuilder.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/freemarker/core/util/CommonBuilder.java b/src/main/java/org/apache/freemarker/core/util/CommonBuilder.java index 8939121..11aab33 100644 --- a/src/main/java/org/apache/freemarker/core/util/CommonBuilder.java +++ b/src/main/java/org/apache/freemarker/core/util/CommonBuilder.java @@ -19,11 +19,17 @@ package org.apache.freemarker.core.util; +import org.apache.freemarker.core.ConfigurationException; + /** * Interface of builders (used for implementing the builder pattern). */ public interface CommonBuilder<ProductT> { - ProductT build(); + /** + * Creates an instance of the product class. This is usually a new instance, though if the product is stateless, + * it's possibly a shared object instead of a new one. + */ + ProductT build() throws ConfigurationException; } http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/7d61a45d/src/main/java/org/apache/freemarker/core/util/_StringUtil.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/freemarker/core/util/_StringUtil.java b/src/main/java/org/apache/freemarker/core/util/_StringUtil.java index 2827c84..50c1874 100644 --- a/src/main/java/org/apache/freemarker/core/util/_StringUtil.java +++ b/src/main/java/org/apache/freemarker/core/util/_StringUtil.java @@ -29,8 +29,8 @@ import java.util.Map; import java.util.StringTokenizer; import java.util.regex.Pattern; -import org.apache.freemarker.core.Configuration; import org.apache.freemarker.core.Environment; +import org.apache.freemarker.core.ParsingConfiguration; import org.apache.freemarker.core.Template; import org.apache.freemarker.core.Version; @@ -1604,21 +1604,21 @@ public class _StringUtil { } /** - * @return {@link Configuration#CAMEL_CASE_NAMING_CONVENTION}, or {@link Configuration#LEGACY_NAMING_CONVENTION} - * or, {@link Configuration#AUTO_DETECT_NAMING_CONVENTION} when undecidable. + * @return {@link ParsingConfiguration#CAMEL_CASE_NAMING_CONVENTION}, or {@link ParsingConfiguration#LEGACY_NAMING_CONVENTION} + * or, {@link ParsingConfiguration#AUTO_DETECT_NAMING_CONVENTION} when undecidable. */ public static int getIdentifierNamingConvention(String name) { final int ln = name.length(); for (int i = 0; i < ln; i++) { final char c = name.charAt(i); if (c == '_') { - return Configuration.LEGACY_NAMING_CONVENTION; + return ParsingConfiguration.LEGACY_NAMING_CONVENTION; } if (_StringUtil.isUpperUSASCII(c)) { - return Configuration.CAMEL_CASE_NAMING_CONVENTION; + return ParsingConfiguration.CAMEL_CASE_NAMING_CONVENTION; } } - return Configuration.AUTO_DETECT_NAMING_CONVENTION; + return ParsingConfiguration.AUTO_DETECT_NAMING_CONVENTION; } // [2.4] Won't be needed anymore http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/7d61a45d/src/main/java/org/apache/freemarker/core/valueformat/TemplateValueFormat.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/freemarker/core/valueformat/TemplateValueFormat.java b/src/main/java/org/apache/freemarker/core/valueformat/TemplateValueFormat.java index 8fb0a0d..9203e5a 100644 --- a/src/main/java/org/apache/freemarker/core/valueformat/TemplateValueFormat.java +++ b/src/main/java/org/apache/freemarker/core/valueformat/TemplateValueFormat.java @@ -29,5 +29,14 @@ public abstract class TemplateValueFormat { * Meant to be used in error messages to tell what format the parsed string didn't fit. */ public abstract String getDescription(); - + + /** + * The implementation in {@link TemplateValueFormat} returns {@code package.className(description)}, where + * description comes from {@link #getDescription()}. + */ + @Override + public String toString() { + return getClass().getName() + "(" + getDescription() + ")"; + } + } http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/7d61a45d/src/main/java/org/apache/freemarker/dom/NodeListModel.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/freemarker/dom/NodeListModel.java b/src/main/java/org/apache/freemarker/dom/NodeListModel.java index 75b9e13..333bb5c 100644 --- a/src/main/java/org/apache/freemarker/dom/NodeListModel.java +++ b/src/main/java/org/apache/freemarker/dom/NodeListModel.java @@ -44,10 +44,9 @@ import org.w3c.dom.NodeList; * Used when the result set contains 0 or multiple nodes; shouldn't be used when you have exactly 1 node. For exactly 1 * node, use {@link NodeModel#wrap(Node)}, because {@link NodeModel} subclasses can have extra features building on that * restriction, like single elements with text content can be used as FTL string-s. - * * <p> - * This class is not guaranteed to be thread safe, so instances of this shouldn't be used as shared variable ( - * {@link Configuration#setSharedVariable(String, Object)}). + * This class is not guaranteed to be thread safe, so instances of this shouldn't be used as + * {@linkplain Configuration#getSharedVariables() shared variable}. */ class NodeListModel extends SimpleSequence implements TemplateHashModel, _UnexpectedTypeErrorExplainerTemplateModel { http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/7d61a45d/src/main/java/org/apache/freemarker/dom/NodeModel.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/freemarker/dom/NodeModel.java b/src/main/java/org/apache/freemarker/dom/NodeModel.java index b1d3cc6..37a5c7d 100644 --- a/src/main/java/org/apache/freemarker/dom/NodeModel.java +++ b/src/main/java/org/apache/freemarker/dom/NodeModel.java @@ -55,23 +55,19 @@ import org.w3c.dom.Text; /** * A base class for wrapping a single W3C DOM_WRAPPER Node as a FreeMarker template model. - * * <p> * Note that {@link DefaultObjectWrapper} automatically wraps W3C DOM_WRAPPER {@link Node}-s into this, so you may need do that * with this class manually. However, before dropping the {@link Node}-s into the data-model, you certainly want to * apply {@link NodeModel#simplify(Node)} on them. - * * <p> - * This class is not guaranteed to be thread safe, so instances of this shouldn't be used as shared variable ( - * {@link Configuration#setSharedVariable(String, Object)}). - * + * This class is not guaranteed to be thread safe, so instances of this shouldn't be used as + * {@linkplain Configuration#getSharedVariables() shared variable}. * <p> * To represent a node sequence (such as a query result) of exactly 1 nodes, this class should be used instead of * {@link NodeListModel}, as it adds extra capabilities by utilizing that we have exactly 1 node. If you need to wrap a * node sequence of 0 or multiple nodes, you must use {@link NodeListModel}. */ -abstract public class NodeModel -implements TemplateNodeModelEx, TemplateHashModel, TemplateSequenceModel, +abstract public class NodeModel implements TemplateNodeModelEx, TemplateHashModel, TemplateSequenceModel, AdapterTemplateModel, WrapperTemplateModel, _UnexpectedTypeErrorExplainerTemplateModel { static private final Logger LOG = DomLog.LOG; http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/7d61a45d/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 3cdc108..b4a2602 100644 --- a/src/main/java/org/apache/freemarker/servlet/FreemarkerServlet.java +++ b/src/main/java/org/apache/freemarker/servlet/FreemarkerServlet.java @@ -41,21 +41,20 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; -import org.apache.freemarker.core.MutableProcessingConfiguration; import org.apache.freemarker.core.Configuration; +import org.apache.freemarker.core.Configuration.ExtendableBuilder; import org.apache.freemarker.core.ConfigurationException; import org.apache.freemarker.core.Environment; +import org.apache.freemarker.core.MutableProcessingConfiguration; import org.apache.freemarker.core.Template; import org.apache.freemarker.core.TemplateException; import org.apache.freemarker.core.TemplateExceptionHandler; import org.apache.freemarker.core.TemplateNotFoundException; -import org.apache.freemarker.core.Version; import org.apache.freemarker.core._CoreLogs; import org.apache.freemarker.core.model.ObjectWrapper; import org.apache.freemarker.core.model.ObjectWrapperAndUnwrapper; import org.apache.freemarker.core.model.TemplateModel; import org.apache.freemarker.core.model.TemplateModelException; -import org.apache.freemarker.core.model.impl.RestrictedObjectWrapper; import org.apache.freemarker.core.model.impl.SimpleHash; import org.apache.freemarker.core.outputformat.OutputFormat; import org.apache.freemarker.core.outputformat.impl.UndefinedOutputFormat; @@ -267,12 +266,13 @@ import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; * * <li>The following init-params are supported only for backward compatibility, and their usage is discouraged: * {@code TemplateUpdateInterval}, {@code DefaultEncoding}, {@code ObjectWrapper}, {@code TemplateExceptionHandler}. - * Instead, use init-params with the setting names documented at {@link Configuration#setSetting(String, String)}, such - * as {@code object_wrapper}. + * Instead, use init-params with the setting names documented at + * {@link ExtendableBuilder#setSetting(String, String)}, such as {@code object_wrapper}. * * <li><strong>Any other init-params</strong> will be interpreted as {@link Configuration}-level FreeMarker setting. See - * the possible names and values at {@link Configuration#setSetting(String, String)}. Note that these init-param names - * are starting with lower-case letter (upper-case init-params are used for FreemarkerSerlvet settings).</li> + * the possible names and values at {@link ExtendableBuilder#setSetting(String, String)}. Note that + * these init-param names are starting with lower-case letter (upper-case init-params are used for FreemarkerSerlvet + * settings).</li> * * </ul> * @@ -412,7 +412,6 @@ public class FreemarkerServlet extends HttpServlet { private static final String DEPR_INITPARAM_TEMPLATE_DELAY = "TemplateDelay"; private static final String DEPR_INITPARAM_ENCODING = "DefaultEncoding"; private static final String DEPR_INITPARAM_OBJECT_WRAPPER = "ObjectWrapper"; - private static final String DEPR_INITPARAM_WRAPPER_RESTRICTED = "restricted"; private static final String DEPR_INITPARAM_TEMPLATE_EXCEPTION_HANDLER = "TemplateExceptionHandler"; private static final String DEPR_INITPARAM_TEMPLATE_EXCEPTION_HANDLER_RETHROW = "rethrow"; private static final String DEPR_INITPARAM_TEMPLATE_EXCEPTION_HANDLER_DEBUG = "debug"; @@ -508,7 +507,6 @@ public class FreemarkerServlet extends HttpServlet { } // Init-param values: - private String templatePath; private boolean noCache; private Integer bufferSize; private boolean exceptionOnMissingTemplate; @@ -522,13 +520,10 @@ public class FreemarkerServlet extends HttpServlet { @SuppressFBWarnings(value="SE_BAD_FIELD", justification="Not investing into making this Servlet serializable") private Configuration config; - @SuppressFBWarnings(value="SE_BAD_FIELD", justification="Not investing into making this Servlet serializable") - private ObjectWrapperAndUnwrapper wrapper; private ContentType contentType; private OverrideResponseContentType overrideResponseContentType = initParamValueToEnum( getDefaultOverrideResponseContentType(), OverrideResponseContentType.values()); private ResponseCharacterEncoding responseCharacterEncoding = ResponseCharacterEncoding.LEGACY; - @SuppressFBWarnings(value="SE_BAD_FIELD", justification="Not investing into making this Servlet serializable") private Charset forcedResponseCharacterEncoding; private OverrideResponseLocale overrideResponseLocale = OverrideResponseLocale.ALWAYS; private List/*<MetaInfTldSource>*/ metaInfTldSources; @@ -544,7 +539,7 @@ public class FreemarkerServlet extends HttpServlet { /** * Don't override this method to adjust FreeMarker settings! Override the protected methods for that, such as - * {@link #createConfiguration()}, {@link #createTemplateLoader(String)}, {@link #createDefaultObjectWrapper()}, + * {@link #createConfigurationBuilder()}, {@link #createTemplateLoader(String)}, * etc. Also note that lot of things can be changed with init-params instead of overriding methods, so if you * override settings, usually you should only override their defaults. */ @@ -560,42 +555,34 @@ public class FreemarkerServlet extends HttpServlet { } } - private void initialize() throws InitParamValueException, MalformedWebXmlException, ConflictingInitParamsException { - config = createConfiguration(); + private void initialize() throws InitParamValueException, MalformedWebXmlException, ConflictingInitParamsException, + ConfigurationException { + Configuration.ExtendableBuilder<?> cfgB = createConfigurationBuilder(); // Only override what's coming from the config if it was explicitly specified: - final String iciInitParamValue = getInitParameter(Configuration.INCOMPATIBLE_IMPROVEMENTS_KEY); + final String iciInitParamValue = getInitParameter(Configuration.ExtendableBuilder.INCOMPATIBLE_IMPROVEMENTS_KEY); if (iciInitParamValue != null) { try { - config.setSetting(Configuration.INCOMPATIBLE_IMPROVEMENTS_KEY, iciInitParamValue); + cfgB.setSetting(Configuration.ExtendableBuilder.INCOMPATIBLE_IMPROVEMENTS_KEY, iciInitParamValue); } catch (Exception e) { - throw new InitParamValueException(Configuration.INCOMPATIBLE_IMPROVEMENTS_KEY, iciInitParamValue, e); + throw new InitParamValueException(Configuration.ExtendableBuilder.INCOMPATIBLE_IMPROVEMENTS_KEY, iciInitParamValue, e); } } - - // Set FreemarkerServlet-specific defaults, except where createConfiguration() has already set them: - if (!config.isTemplateExceptionHandlerExplicitlySet()) { - config.setTemplateExceptionHandler(TemplateExceptionHandler.HTML_DEBUG_HANDLER); - } - if (!config.isLogTemplateExceptionsExplicitlySet()) { - config.setLogTemplateExceptions(false); - } - + contentType = DEFAULT_CONTENT_TYPE; - // Process object_wrapper init-param out of order: - wrapper = createObjectWrapper(); - LOG.debug("Using object wrapper {}", wrapper); - config.setObjectWrapper(wrapper); - - // Process TemplatePath init-param out of order: - templatePath = getInitParameter(INIT_PARAM_TEMPLATE_PATH); - if (templatePath == null && !config.isTemplateLoaderExplicitlySet()) { - templatePath = InitParamParser.TEMPLATE_PATH_PREFIX_CLASS; + // Process object_wrapper init-param out of order: + String objectWrapperInitParamValue = getInitParameter( + MutableProcessingConfiguration.OBJECT_WRAPPER_KEY, DEPR_INITPARAM_OBJECT_WRAPPER); + if (objectWrapperInitParamValue != null) { + setObjectWrapperFromInitParam(cfgB, objectWrapperInitParamValue); } + + // Process TemplatePath init-param out of order: + String templatePath = getInitParameter(INIT_PARAM_TEMPLATE_PATH); if (templatePath != null) { try { - config.setTemplateLoader(createTemplateLoader(templatePath)); + cfgB.setTemplateLoader(createTemplateLoader(templatePath)); } catch (Exception e) { throw new InitParamValueException(INIT_PARAM_TEMPLATE_PATH, templatePath, e); } @@ -605,9 +592,8 @@ public class FreemarkerServlet extends HttpServlet { classpathTlds = createDefaultClassPathTlds(); // Process all other init-params: - Enumeration initpnames = getServletConfig().getInitParameterNames(); - while (initpnames.hasMoreElements()) { - final String name = (String) initpnames.nextElement(); + for (Enumeration initPNames = getServletConfig().getInitParameterNames(); initPNames.hasMoreElements();) { + final String name = (String) initPNames.nextElement(); final String value = getInitParameter(name); if (name == null) { throw new MalformedWebXmlException( @@ -624,21 +610,21 @@ public class FreemarkerServlet extends HttpServlet { if (name.equals(DEPR_INITPARAM_OBJECT_WRAPPER) || name.equals(MutableProcessingConfiguration.OBJECT_WRAPPER_KEY) || name.equals(INIT_PARAM_TEMPLATE_PATH) - || name.equals(Configuration.INCOMPATIBLE_IMPROVEMENTS_KEY)) { + || name.equals(Configuration.ExtendableBuilder.INCOMPATIBLE_IMPROVEMENTS_KEY)) { // ignore: we have already processed these } else if (name.equals(DEPR_INITPARAM_ENCODING)) { // BC - if (getInitParameter(Configuration.SOURCE_ENCODING_KEY) != null) { + if (getInitParameter(Configuration.ExtendableBuilder.SOURCE_ENCODING_KEY) != null) { throw new ConflictingInitParamsException( - Configuration.SOURCE_ENCODING_KEY, DEPR_INITPARAM_ENCODING); + Configuration.ExtendableBuilder.SOURCE_ENCODING_KEY, DEPR_INITPARAM_ENCODING); } - config.setSourceEncoding(Charset.forName(value)); + cfgB.setSourceEncoding(Charset.forName(value)); } else if (name.equals(DEPR_INITPARAM_TEMPLATE_DELAY)) { // BC - if (getInitParameter(Configuration.TEMPLATE_UPDATE_DELAY_KEY) != null) { + if (getInitParameter(Configuration.ExtendableBuilder.TEMPLATE_UPDATE_DELAY_KEY) != null) { throw new ConflictingInitParamsException( - Configuration.TEMPLATE_UPDATE_DELAY_KEY, DEPR_INITPARAM_TEMPLATE_DELAY); + Configuration.ExtendableBuilder.TEMPLATE_UPDATE_DELAY_KEY, DEPR_INITPARAM_TEMPLATE_DELAY); } try { - config.setTemplateUpdateDelayMilliseconds(Integer.parseInt(value) * 1000L); + cfgB.setTemplateUpdateDelayMilliseconds(Integer.parseInt(value) * 1000L); } catch (NumberFormatException e) { // Intentionally ignored } @@ -649,13 +635,13 @@ public class FreemarkerServlet extends HttpServlet { } if (DEPR_INITPARAM_TEMPLATE_EXCEPTION_HANDLER_RETHROW.equals(value)) { - config.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER); + cfgB.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER); } else if (DEPR_INITPARAM_TEMPLATE_EXCEPTION_HANDLER_DEBUG.equals(value)) { - config.setTemplateExceptionHandler(TemplateExceptionHandler.DEBUG_HANDLER); + cfgB.setTemplateExceptionHandler(TemplateExceptionHandler.DEBUG_HANDLER); } else if (DEPR_INITPARAM_TEMPLATE_EXCEPTION_HANDLER_HTML_DEBUG.equals(value)) { - config.setTemplateExceptionHandler(TemplateExceptionHandler.HTML_DEBUG_HANDLER); + cfgB.setTemplateExceptionHandler(TemplateExceptionHandler.HTML_DEBUG_HANDLER); } else if (DEPR_INITPARAM_TEMPLATE_EXCEPTION_HANDLER_IGNORE.equals(value)) { - config.setTemplateExceptionHandler(TemplateExceptionHandler.IGNORE_HANDLER); + cfgB.setTemplateExceptionHandler(TemplateExceptionHandler.IGNORE_HANDLER); } else { throw new InitParamValueException(DEPR_INITPARAM_TEMPLATE_EXCEPTION_HANDLER, value, "Not one of the supported values."); @@ -695,21 +681,32 @@ public class FreemarkerServlet extends HttpServlet { newClasspathTlds.addAll(InitParamParser.parseCommaSeparatedList(value)); classpathTlds = newClasspathTlds; } else { - config.setSetting(name, value); + cfgB.setSetting(name, value); } } catch (ConflictingInitParamsException e) { throw e; } catch (Exception e) { throw new InitParamValueException(name, value, e); } - } // while initpnames + } // for initPNames if (contentType.containsCharset && responseCharacterEncoding != ResponseCharacterEncoding.LEGACY) { throw new InitParamValueException(INIT_PARAM_CONTENT_TYPE, contentType.httpHeaderValue, new IllegalStateException("You can't specify the charset in the content type, because the \"" + INIT_PARAM_RESPONSE_CHARACTER_ENCODING + "\" init-param isn't set to " + "\"" + INIT_PARAM_VALUE_LEGACY + "\".")); - } + } + + beforeConfigurationBuilt(cfgB); + config = cfgB.build(); + afterConfigurationBuilt(config); + + if (!(config.getObjectWrapper() instanceof ObjectWrapperAndUnwrapper)) { + throw new RuntimeException(FreemarkerServlet.class.getSimpleName() + " requires an ObjectWrapper that " + + "implements " + ObjectWrapperAndUnwrapper.class.getName() + ", but this class doesn't do that: " + + config.getObjectWrapper().getClass().getName()); + } + LOG.debug("Using object wrapper {}", config.getObjectWrapper()); } private List/*<MetaInfTldSource>*/ parseAsMetaInfTldLocations(String value) throws ParseException { @@ -751,18 +748,18 @@ public class FreemarkerServlet extends HttpServlet { } /** - * Create the template loader. The default implementation will invoke a {@link ClassTemplateLoader} if the template + * Create the template loader. The default implementation will create a {@link ClassTemplateLoader} if the template * path starts with {@code "class://"}, a {@link FileTemplateLoader} if the template path starts with * {@code "file://"}, and a {@link WebAppTemplateLoader} otherwise. Also, if - * {@link Configuration#Configuration(org.apache.freemarker.core.Version) incompatible_improvements} is 2.3.22 or higher, - * it will invoke a {@link MultiTemplateLoader} if the template path starts with {@code "["}. + * {@link Configuration#getIncompatibleImprovements()} incompatibleImprovements} is 2.3.22 or higher, + * it will create a {@link MultiTemplateLoader} if the template path starts with {@code "["}. * * @param templatePath - * the template path to invoke a loader for + * the template path to create a loader for * @return a newly created template loader */ protected TemplateLoader createTemplateLoader(String templatePath) throws IOException { - return InitParamParser.createTemplateLoader(templatePath, getConfiguration(), getClass(), getServletContext()); + return InitParamParser.createTemplateLoader(templatePath, getClass(), getServletContext()); } @Override @@ -868,9 +865,9 @@ public class FreemarkerServlet extends HttpServlet { ServletContext servletContext = getServletContext(); try { - logWarnOnObjectWrapperMismatch(); - - TemplateModel model = createModel(wrapper, servletContext, request, response); + TemplateModel model = createModel( + (ObjectWrapperAndUnwrapper) config.getObjectWrapper(), // This is checked in initialize() + servletContext, request, response); // Give subclasses a chance to hook into preprocessing if (preTemplateProcess(request, response, template, model)) { @@ -978,26 +975,6 @@ public class FreemarkerServlet extends HttpServlet { throw e; } - @SuppressFBWarnings(value={ "MSF_MUTABLE_SERVLET_FIELD", "DC_DOUBLECHECK" }, justification="Performance trick") - private void logWarnOnObjectWrapperMismatch() { - // Deliberately uses double check locking. - if (wrapper != config.getObjectWrapper() && !objectWrapperMismatchWarnLogged && LOG.isWarnEnabled()) { - final boolean logWarn; - synchronized (this) { - logWarn = !objectWrapperMismatchWarnLogged; - if (logWarn) { - objectWrapperMismatchWarnLogged = true; - } - } - if (logWarn) { - LOG.warn( - getClass().getName() - + ".wrapper != config.getObjectWrapper(); possibly the result of incorrect extension of " - + FreemarkerServlet.class.getName() + "."); - } - } - } - /** * Returns the locale used for the {@link Configuration#getTemplate(String, Locale)} call (as far as the * {@value #INIT_PARAM_OVERRIDE_RESPONSE_LOCALE} Servlet init-param allows that). The base implementation in @@ -1091,7 +1068,7 @@ public class FreemarkerServlet extends HttpServlet { } /** - * Called to invoke the {@link TaglibFactory} once per servlet context. + * Called to create the {@link TaglibFactory} once per servlet context. * The default implementation configures it based on the servlet-init parameters and various other environmental * settings, so if you override this method, you should call super, then adjust the result. * @@ -1258,128 +1235,60 @@ public class FreemarkerServlet extends HttpServlet { } /** - * Creates the FreeMarker {@link Configuration} singleton and (when overidden) maybe sets its defaults. Servlet - * init-params will be applied later, and thus can overwrite the settings specified here. - * + * Creates a new FreeMarker {@link Configuration} builder; by providing a custom builder, the configuration + * setting defaults can be specific to the {@link FreemarkerServlet} subclass. * <p> - * By overriding this method you can set your preferred {@link Configuration} setting defaults, as only the settings - * for which an init-param was specified will be overwritten later. (Note that {@link FreemarkerServlet} also has - * its own defaults for a few settings, but since 2.3.22, the servlet detects if those settings were already set - * here and then it won't overwrite them.) - * + * The default implementation creates a new {@link FreemarkerServletConfigurationBuilder} instance (note that it's + * not the standard {@link Configuration} builder, as some setting defaults differ) with + * {@link Configuration#getIncompatibleImprovements() incompatibleImprovements} + * {@link Configuration#VERSION_3_0_0}. * <p> - * The default implementation simply creates a new instance with {@link Configuration#Configuration()} and returns - * it. + * By overriding this method you can use your own {@link FreemarkerServletConfigurationBuilder} subclass + * (or actually any {@link ExtendableBuilder} subclass) and hence specify what the defaults are. */ - protected Configuration createConfiguration() { - // We can only set incompatible_improvements later, so ignore the deprecation warning here. - return new Configuration(); + protected Configuration.ExtendableBuilder<?> createConfigurationBuilder() { + return new FreemarkerServletConfigurationBuilder(this, Configuration.VERSION_3_0_0); } /** - * Sets the defaults of the configuration that are specific to the {@link FreemarkerServlet} subclass. - * This is called after the common (wired in) {@link FreemarkerServlet} setting defaults was set, also the - */ - protected void setConfigurationDefaults() { - // do nothing - } - - /** - * Called from {@link #init()} to invoke the {@link ObjectWrapper}; to customzie this aspect, in most cases you - * should override {@link #createDefaultObjectWrapper()} instead. Overriding this method is necessary when you want - * to customize how the {@link ObjectWrapper} is created <em>from the init-param values</em>, or you want to do some - * post-processing (like checking) on the created {@link ObjectWrapper}. To customize init-param interpretation, - * call {@link #getInitParameter(String)} with {@link MutableProcessingConfiguration#OBJECT_WRAPPER_KEY} as argument, and see if it - * returns a value that you want to interpret yourself. If was {@code null} or you don't want to interpret the - * value, fall back to the super method. - * + * Hook for {@link FreemarkerServlet} subclasses to modify the configuration builder just before the + * {@link Configuration} is created. Note that to change the defaults of some setting, you meant to use + * {@link #createConfigurationBuilder()} instead. * <p> - * The default implementation interprets the {@code object_wrapper} servlet init-param with - * calling {@link MutableProcessingConfiguration#setSetting(String, String)} (see valid values there), or if there's no such servlet - * init-param, then it calls {@link #createDefaultObjectWrapper()}. - * - * @return The {@link ObjectWrapper} that will be used for adapting request, session, and servlet context attributes - * to {@link TemplateModel}-s, and also as the object wrapper setting of {@link Configuration}. + * The implementation in {@link FreemarkerServlet} does nothing here. */ - protected ObjectWrapperAndUnwrapper createObjectWrapper() { - String wrapper = getServletConfig().getInitParameter(DEPR_INITPARAM_OBJECT_WRAPPER); - if (wrapper != null) { // BC - if (getInitParameter(MutableProcessingConfiguration.OBJECT_WRAPPER_KEY) != null) { - throw new RuntimeException("Conflicting init-params: " - + MutableProcessingConfiguration.OBJECT_WRAPPER_KEY + " and " - + DEPR_INITPARAM_OBJECT_WRAPPER); - } - if (DEPR_INITPARAM_WRAPPER_RESTRICTED.equals(wrapper)) { - return new RestrictedObjectWrapper.Builder(Configuration.VERSION_3_0_0).build(); - } - return createDefaultObjectWrapper(); - } else { - wrapper = getInitParameter(MutableProcessingConfiguration.OBJECT_WRAPPER_KEY); - if (wrapper == null) { - if (!config.isObjectWrapperExplicitlySet()) { - return createDefaultObjectWrapper(); - } else { - return asObjectWrapperAndUnwrapper(config.getObjectWrapper()); - } - } else { - try { - config.setSetting(MutableProcessingConfiguration.OBJECT_WRAPPER_KEY, wrapper); - } catch (ConfigurationException e) { - throw new RuntimeException("Failed to set " + MutableProcessingConfiguration.OBJECT_WRAPPER_KEY, e); - } - return asObjectWrapperAndUnwrapper(config.getObjectWrapper()); - } - } - } - - private ObjectWrapperAndUnwrapper asObjectWrapperAndUnwrapper(ObjectWrapper objectWrapper) { - if (!(objectWrapper instanceof ObjectWrapperAndUnwrapper)) { - throw new RuntimeException(FreemarkerServlet.class.getSimpleName() + " requires an ObjectWrapper that " + - "implements " + ObjectWrapperAndUnwrapper.class.getName() + ", but this class doesn't do that: " - + objectWrapper.getClass().getName()); - } - return (ObjectWrapperAndUnwrapper) objectWrapper; + protected void beforeConfigurationBuilt(Configuration.ExtendableBuilder<?> cfgB) { + // do nothing } /** - * Override this to specify what the default {@link ObjectWrapper} will be when the - * {@code object_wrapper} Servlet init-param wasn't specified. Note that this is called by - * {@link #createConfiguration()}, and so if that was also overidden but improperly then this method might won't be - * ever called. Also note that if you set the {@code object_wrapper} in {@link #createConfiguration()}, then this - * won't be called, since then that has already specified the default. - * + * Hook for {@link FreemarkerServlet} subclasses to examine {@link Configuration} just after it was created. * <p> - * The default implementation calls {@link Configuration#getDefaultObjectWrapper(Version)}. You - * should also pass in the version paramter when creating an {@link ObjectWrapper} that supports that. You can get - * the version by calling {@link #getConfiguration()} and then {@link Configuration#getIncompatibleImprovements()}. - * - * @since 2.3.22 - */ - protected ObjectWrapperAndUnwrapper createDefaultObjectWrapper() { - return Configuration.getDefaultObjectWrapper(config.getIncompatibleImprovements()); - } - - /** - * Should be final; don't override it. Override {@link #createObjectWrapper()} instead. + * The implementation in {@link FreemarkerServlet} does nothing here. */ - // [2.4] Make it final - protected ObjectWrapper getObjectWrapper() { - return wrapper; + protected void afterConfigurationBuilt(Configuration cfg) { + // do nothing } /** - * The value of the {@code TemplatePath} init-param. {@code null} if the {@code template_loader} setting was set in - * a custom {@link #createConfiguration()}. - * - * @deprecated Not called by FreeMarker code, and there's no point to override this (unless to cause confusion). + * Called from {@link #init()} to set the {@link ObjectWrapper} in the {@link ExtendableBuilder} + * from the init-param value. + * To customize init-param interpretation, see if the init-param value argument is something that you want to + * interpret yourself, otherwise fall back to the super method. This method won't be called if there's not + * init-param that specifies the object wrapper. + * <p> + * The default implementation interprets the {@code object_wrapper} servlet init-param with + * calling {@link MutableProcessingConfiguration#setSetting(String, String)}. + * + * @param initParamValue Not {@code null} */ - @Deprecated - protected final String getTemplatePath() { - return templatePath; + protected void setObjectWrapperFromInitParam(Configuration.ExtendableBuilder<?> cb, String initParamValue) + throws ConfigurationException { + cb.setSetting(MutableProcessingConfiguration.OBJECT_WRAPPER_KEY, initParamValue); } - + protected HttpRequestParametersHashModel createRequestParametersHashModel(HttpServletRequest request) { - return new HttpRequestParametersHashModel(request, getObjectWrapper()); + return new HttpRequestParametersHashModel(request, config.getObjectWrapper()); } /** @@ -1628,6 +1537,15 @@ public class FreemarkerServlet extends HttpServlet { throw new IllegalArgumentException(sb.toString()); } + private String getInitParameter(String name1, String name2) { + String r1 = getServletConfig().getInitParameter(name1); + String r2 = getInitParameter(name2); + if (r1 != null && r2 != null) { + throw new RuntimeException("Conflicting init-params: " + name1 + " and " + name2); + } + return r2 != null ? r2 : r1; + } + /** * Superclass of all (future) init-param value enums. * @@ -1689,4 +1607,5 @@ public class FreemarkerServlet extends HttpServlet { } } + } http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/7d61a45d/src/main/java/org/apache/freemarker/servlet/FreemarkerServletConfigurationBuilder.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/freemarker/servlet/FreemarkerServletConfigurationBuilder.java b/src/main/java/org/apache/freemarker/servlet/FreemarkerServletConfigurationBuilder.java new file mode 100644 index 0000000..c3eee4d --- /dev/null +++ b/src/main/java/org/apache/freemarker/servlet/FreemarkerServletConfigurationBuilder.java @@ -0,0 +1,79 @@ +/* + * 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.servlet; + +import java.io.IOException; + +import org.apache.freemarker.core.Configuration; +import org.apache.freemarker.core.Configuration.ExtendableBuilder; +import org.apache.freemarker.core.TemplateExceptionHandler; +import org.apache.freemarker.core.Version; +import org.apache.freemarker.core.templateresolver.TemplateLoader; + +/** + * Changes some defaults compared to {@link ExtendableBuilder}, to values that makes more sense for the + * {@link FreemarkerServlet}. + */ +// TODO [FM3] JavaDoc the defaults when they are stable +public class FreemarkerServletConfigurationBuilder<SelfT extends FreemarkerServletConfigurationBuilder<SelfT>> + extends Configuration.ExtendableBuilder<SelfT> { + + private final FreemarkerServlet freemarkerServlet; + private TemplateLoader cachedDefaultTemplateLoader; + + public FreemarkerServletConfigurationBuilder(FreemarkerServlet freemarkerServlet, Version version) { + super(version); + this.freemarkerServlet = freemarkerServlet; + } + + @Override + protected TemplateExceptionHandler getDefaultTemplateExceptionHandler() { + // TODO [FM3] Not a good default. Should depend on if we are in development mode or production mode. + return TemplateExceptionHandler.HTML_DEBUG_HANDLER; + } + + // TODO [FM3] Remove when this will be the ExtendableBuilder default too. + @Override + protected boolean getDefaultLogTemplateExceptions() { + return false; + } + + @Override + public void setTemplateLoader(TemplateLoader templateLoader) { + super.setTemplateLoader(templateLoader); + if (cachedDefaultTemplateLoader != templateLoader) { + // Just to make it GC-able + cachedDefaultTemplateLoader = null; + } + } + + @Override + protected TemplateLoader getDefaultTemplateLoader() { + try { + if (cachedDefaultTemplateLoader == null) { + cachedDefaultTemplateLoader = freemarkerServlet.createTemplateLoader(InitParamParser.TEMPLATE_PATH_PREFIX_CLASS); + } + return cachedDefaultTemplateLoader; + } catch (IOException e) { + // It's almost impossible that this will happen + throw new RuntimeException("Failed to create default template loader; see cause exception", e); + } + } +} http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/7d61a45d/src/main/java/org/apache/freemarker/servlet/InitParamParser.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/freemarker/servlet/InitParamParser.java b/src/main/java/org/apache/freemarker/servlet/InitParamParser.java index 0f20b7b..de8e780 100644 --- a/src/main/java/org/apache/freemarker/servlet/InitParamParser.java +++ b/src/main/java/org/apache/freemarker/servlet/InitParamParser.java @@ -27,7 +27,6 @@ import java.util.regex.Pattern; import javax.servlet.ServletContext; -import org.apache.freemarker.core.Configuration; import org.apache.freemarker.core._ObjectBuilderSettingEvaluator; import org.apache.freemarker.core._SettingEvaluationEnvironment; import org.apache.freemarker.core.templateresolver.TemplateLoader; @@ -54,7 +53,7 @@ final class InitParamParser { } static TemplateLoader createTemplateLoader( - String templatePath, Configuration cfg, Class classLoaderClass, ServletContext srvCtx) + String templatePath, Class classLoaderClass, ServletContext srvCtx) throws IOException { final int settingAssignmentsStart = findTemplatePathSettingAssignmentsStart(templatePath); String pureTemplatePath = (settingAssignmentsStart == -1 ? templatePath : templatePath.substring(0, settingAssignmentsStart)) @@ -91,7 +90,7 @@ final class InitParamParser { TemplateLoader[] templateLoaders = new TemplateLoader[listItems.size()]; for (int i = 0; i < listItems.size(); i++) { String pathItem = (String) listItems.get(i); - templateLoaders[i] = createTemplateLoader(pathItem, cfg, classLoaderClass, srvCtx); + templateLoaders[i] = createTemplateLoader(pathItem, classLoaderClass, srvCtx); } templateLoader = new MultiTemplateLoader(templateLoaders); } else if (pureTemplatePath.startsWith("{")) { http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/7d61a45d/src/main/java/org/apache/freemarker/servlet/WebAppTemplateLoader.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/freemarker/servlet/WebAppTemplateLoader.java b/src/main/java/org/apache/freemarker/servlet/WebAppTemplateLoader.java index be215d5..9be5834 100644 --- a/src/main/java/org/apache/freemarker/servlet/WebAppTemplateLoader.java +++ b/src/main/java/org/apache/freemarker/servlet/WebAppTemplateLoader.java @@ -155,7 +155,7 @@ public class WebAppTemplateLoader implements TemplateLoader { * workaround for the case when the servlet container doesn't show template modifications after the template was * already loaded earlier. But it's certainly better to counter this problem by disabling the URL connection cache * with {@link #setURLConnectionUsesCaches(Boolean)}, which is also the default behavior with - * {@link Configuration#setIncompatibleImprovements(org.apache.freemarker.core.Version) incompatible_improvements} 2.3.21 + * {@link Configuration#getIncompatibleImprovements() incompatibleImprovements} 2.3.21 * and later. * * @since 2.3.23 http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/7d61a45d/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 9399918..e5a898e 100644 --- a/src/manual/en_US/FM3-CHANGE-LOG.txt +++ b/src/manual/en_US/FM3-CHANGE-LOG.txt @@ -212,4 +212,15 @@ the FreeMarer 3 changelog here: lookup and the source name, its meaning wasn't clean (but it meant the lookup name). TemplateException and ParseException now also have the same properites: getTemplateSourceName(), getTemplateLookupName(), and even getSourceOrLookupName(). Location information in error messages show getTemplateSourceOrLookupName(). -- Configuration.setSharedVaribles (not the typo in it) was renamed to setSharedVariables \ No newline at end of file +- Configuration.setSharedVaribles (not the typo in it) was renamed to setSharedVariables +- Configuration is now immutable. Instead, you should use Configuration.Builder to set up the setting values, then create + the Configuration with the builder's build() method. Further notes: + - Most of the mutator methods (like setters) were moved from Configuration to Configuration.Builder. However, + setClassForTemplateLoader, setDirectoryForTemplateLoading and the like were removed, instead there's just + setTemplateLoader. So for example. instead of setClassForTemplateLoader(Foo.class, "templates") now you have + to write setTemplateLoader(new ClassTemplateLoader(Foo.class, "templates")). While it's a bit longer, it shows + more clearly what's happening, and always supports all TemplateLoader constructor overloads. + - It's now possible to change the Configuration setting defaults by using a custom Configuration.ExtendableBuilder + subclass instead of Configuration.Builder (which is also an ExtendableBuilder subclass). FreemarkerServlet has + switched to this approach, using its own builder subclass to provide defaults that makes the sense in that particular + application. Its API-s which were used for customizing FreemarkerServlet has bean changed accordingly. \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/7d61a45d/src/test/java/org/apache/freemarker/core/ASTPrinter.java ---------------------------------------------------------------------- diff --git a/src/test/java/org/apache/freemarker/core/ASTPrinter.java b/src/test/java/org/apache/freemarker/core/ASTPrinter.java index ddd8e9b..3518b29 100644 --- a/src/test/java/org/apache/freemarker/core/ASTPrinter.java +++ b/src/test/java/org/apache/freemarker/core/ASTPrinter.java @@ -43,6 +43,7 @@ import org.apache.freemarker.core.model.TemplateModel; import org.apache.freemarker.core.util.FTLUtil; import org.apache.freemarker.core.util._ClassUtil; import org.apache.freemarker.core.util._StringUtil; +import org.apache.freemarker.test.TestConfigurationBuilder; /** * Static methods and command-line tool for printing the AST of a template. @@ -68,7 +69,7 @@ public class ASTPrinter { } private ASTPrinter() { - cfg = new Configuration(Configuration.VERSION_3_0_0); + cfg = new TestConfigurationBuilder(Configuration.VERSION_3_0_0).build(); } private void mainSingleTemplate(String[] args) throws IOException, FileNotFoundException { @@ -230,8 +231,7 @@ public class ASTPrinter { } public static String getASTAsString(String templateName, String ftl, Options opts) throws IOException { - Configuration cfg = new Configuration(); - Template t = new Template(templateName, ftl, cfg); + Template t = new Template(templateName, ftl, new TestConfigurationBuilder().build()); return getASTAsString(t, opts); } http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/7d61a45d/src/test/java/org/apache/freemarker/core/ActualNamingConvetionTest.java ---------------------------------------------------------------------- diff --git a/src/test/java/org/apache/freemarker/core/ActualNamingConvetionTest.java b/src/test/java/org/apache/freemarker/core/ActualNamingConvetionTest.java index ea07e1f..57e40fa 100644 --- a/src/test/java/org/apache/freemarker/core/ActualNamingConvetionTest.java +++ b/src/test/java/org/apache/freemarker/core/ActualNamingConvetionTest.java @@ -23,6 +23,7 @@ import static org.junit.Assert.*; import java.io.IOException; +import org.apache.freemarker.test.TestConfigurationBuilder; import org.junit.Test; public class ActualNamingConvetionTest { @@ -31,35 +32,35 @@ public class ActualNamingConvetionTest { public void testUndetectable() throws IOException { final String ftl = "<#if true>${x?size}</#if>"; assertEquals(getActualNamingConvention(ftl, - Configuration.AUTO_DETECT_NAMING_CONVENTION), Configuration.AUTO_DETECT_NAMING_CONVENTION); + ParsingConfiguration.AUTO_DETECT_NAMING_CONVENTION), ParsingConfiguration.AUTO_DETECT_NAMING_CONVENTION); assertEquals(getActualNamingConvention(ftl, - Configuration.LEGACY_NAMING_CONVENTION), Configuration.LEGACY_NAMING_CONVENTION); + ParsingConfiguration.LEGACY_NAMING_CONVENTION), ParsingConfiguration.LEGACY_NAMING_CONVENTION); assertEquals(getActualNamingConvention(ftl, - Configuration.CAMEL_CASE_NAMING_CONVENTION), Configuration.CAMEL_CASE_NAMING_CONVENTION); + ParsingConfiguration.CAMEL_CASE_NAMING_CONVENTION), ParsingConfiguration.CAMEL_CASE_NAMING_CONVENTION); } @Test public void testLegacyDetected() throws IOException { final String ftl = "${x?upper_case}"; assertEquals(getActualNamingConvention(ftl, - Configuration.AUTO_DETECT_NAMING_CONVENTION), Configuration.LEGACY_NAMING_CONVENTION); + ParsingConfiguration.AUTO_DETECT_NAMING_CONVENTION), ParsingConfiguration.LEGACY_NAMING_CONVENTION); assertEquals(getActualNamingConvention(ftl, - Configuration.LEGACY_NAMING_CONVENTION), Configuration.LEGACY_NAMING_CONVENTION); + ParsingConfiguration.LEGACY_NAMING_CONVENTION), ParsingConfiguration.LEGACY_NAMING_CONVENTION); } @Test public void testCamelCaseDetected() throws IOException { final String ftl = "${x?upperCase}"; assertEquals(getActualNamingConvention(ftl, - Configuration.AUTO_DETECT_NAMING_CONVENTION), Configuration.CAMEL_CASE_NAMING_CONVENTION); + ParsingConfiguration.AUTO_DETECT_NAMING_CONVENTION), ParsingConfiguration.CAMEL_CASE_NAMING_CONVENTION); assertEquals(getActualNamingConvention(ftl, - Configuration.CAMEL_CASE_NAMING_CONVENTION), Configuration.CAMEL_CASE_NAMING_CONVENTION); + ParsingConfiguration.CAMEL_CASE_NAMING_CONVENTION), ParsingConfiguration.CAMEL_CASE_NAMING_CONVENTION); } private int getActualNamingConvention(String ftl, int namingConvention) throws IOException { - Configuration cfg = new Configuration(); - cfg.setNamingConvention(namingConvention); - return new Template(null, ftl, cfg).getActualNamingConvention(); + return new Template(null, ftl, + new TestConfigurationBuilder().namingConvention(namingConvention).build()) + .getActualNamingConvention(); } } http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/7d61a45d/src/test/java/org/apache/freemarker/core/ActualTagSyntaxTest.java ---------------------------------------------------------------------- diff --git a/src/test/java/org/apache/freemarker/core/ActualTagSyntaxTest.java b/src/test/java/org/apache/freemarker/core/ActualTagSyntaxTest.java index 58c101f..88f0646 100644 --- a/src/test/java/org/apache/freemarker/core/ActualTagSyntaxTest.java +++ b/src/test/java/org/apache/freemarker/core/ActualTagSyntaxTest.java @@ -19,48 +19,50 @@ package org.apache.freemarker.core; +import static org.apache.freemarker.core.ParsingConfiguration.*; import static org.junit.Assert.*; import java.io.IOException; +import org.apache.freemarker.test.TestConfigurationBuilder; import org.junit.Test; public class ActualTagSyntaxTest { @Test public void testWithFtlHeader() throws IOException { - testWithFtlHeader(Configuration.AUTO_DETECT_TAG_SYNTAX); - testWithFtlHeader(Configuration.ANGLE_BRACKET_TAG_SYNTAX); - testWithFtlHeader(Configuration.SQUARE_BRACKET_TAG_SYNTAX); + testWithFtlHeader(AUTO_DETECT_TAG_SYNTAX); + testWithFtlHeader(ANGLE_BRACKET_TAG_SYNTAX); + testWithFtlHeader(SQUARE_BRACKET_TAG_SYNTAX); } private void testWithFtlHeader(int cfgTagSyntax) throws IOException { - assertEquals(getActualTagSyntax("[#ftl]foo", cfgTagSyntax), Configuration.SQUARE_BRACKET_TAG_SYNTAX); - assertEquals(getActualTagSyntax("<#ftl>foo", cfgTagSyntax), Configuration.ANGLE_BRACKET_TAG_SYNTAX); + assertEquals(getActualTagSyntax("[#ftl]foo", cfgTagSyntax), SQUARE_BRACKET_TAG_SYNTAX); + assertEquals(getActualTagSyntax("<#ftl>foo", cfgTagSyntax), ANGLE_BRACKET_TAG_SYNTAX); } @Test public void testUndecidable() throws IOException { - assertEquals(getActualTagSyntax("foo", Configuration.AUTO_DETECT_TAG_SYNTAX), Configuration.ANGLE_BRACKET_TAG_SYNTAX); - assertEquals(getActualTagSyntax("foo", Configuration.ANGLE_BRACKET_TAG_SYNTAX), Configuration.ANGLE_BRACKET_TAG_SYNTAX); - assertEquals(getActualTagSyntax("foo", Configuration.SQUARE_BRACKET_TAG_SYNTAX), Configuration.SQUARE_BRACKET_TAG_SYNTAX); + assertEquals(getActualTagSyntax("foo", AUTO_DETECT_TAG_SYNTAX), ANGLE_BRACKET_TAG_SYNTAX); + assertEquals(getActualTagSyntax("foo", ANGLE_BRACKET_TAG_SYNTAX), ANGLE_BRACKET_TAG_SYNTAX); + assertEquals(getActualTagSyntax("foo", SQUARE_BRACKET_TAG_SYNTAX), SQUARE_BRACKET_TAG_SYNTAX); } @Test public void testDecidableWithoutFtlHeader() throws IOException { - assertEquals(getActualTagSyntax("foo<#if true></#if>", Configuration.AUTO_DETECT_TAG_SYNTAX), Configuration.ANGLE_BRACKET_TAG_SYNTAX); - assertEquals(getActualTagSyntax("foo<#if true></#if>", Configuration.ANGLE_BRACKET_TAG_SYNTAX), Configuration.ANGLE_BRACKET_TAG_SYNTAX); - assertEquals(getActualTagSyntax("foo<#if true></#if>", Configuration.SQUARE_BRACKET_TAG_SYNTAX), Configuration.SQUARE_BRACKET_TAG_SYNTAX); + assertEquals(getActualTagSyntax("foo<#if true></#if>", AUTO_DETECT_TAG_SYNTAX), ANGLE_BRACKET_TAG_SYNTAX); + assertEquals(getActualTagSyntax("foo<#if true></#if>", ANGLE_BRACKET_TAG_SYNTAX), ANGLE_BRACKET_TAG_SYNTAX); + assertEquals(getActualTagSyntax("foo<#if true></#if>", SQUARE_BRACKET_TAG_SYNTAX), SQUARE_BRACKET_TAG_SYNTAX); - assertEquals(getActualTagSyntax("foo[#if true][/#if]", Configuration.AUTO_DETECT_TAG_SYNTAX), Configuration.SQUARE_BRACKET_TAG_SYNTAX); - assertEquals(getActualTagSyntax("foo[#if true][/#if]", Configuration.ANGLE_BRACKET_TAG_SYNTAX), Configuration.ANGLE_BRACKET_TAG_SYNTAX); - assertEquals(getActualTagSyntax("foo[#if true][/#if]", Configuration.SQUARE_BRACKET_TAG_SYNTAX), Configuration.SQUARE_BRACKET_TAG_SYNTAX); + assertEquals(getActualTagSyntax("foo[#if true][/#if]", AUTO_DETECT_TAG_SYNTAX), SQUARE_BRACKET_TAG_SYNTAX); + assertEquals(getActualTagSyntax("foo[#if true][/#if]", ANGLE_BRACKET_TAG_SYNTAX), ANGLE_BRACKET_TAG_SYNTAX); + assertEquals(getActualTagSyntax("foo[#if true][/#if]", SQUARE_BRACKET_TAG_SYNTAX), SQUARE_BRACKET_TAG_SYNTAX); } private int getActualTagSyntax(String ftl, int cfgTagSyntax) throws IOException { - Configuration cfg = new Configuration(); - cfg.setTagSyntax(cfgTagSyntax); - return new Template(null, ftl, cfg).getActualTagSyntax(); + return new Template( + null, ftl, + new TestConfigurationBuilder().tagSyntax(cfgTagSyntax).build()).getActualTagSyntax(); } } http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/7d61a45d/src/test/java/org/apache/freemarker/core/BreakPlacementTest.java ---------------------------------------------------------------------- diff --git a/src/test/java/org/apache/freemarker/core/BreakPlacementTest.java b/src/test/java/org/apache/freemarker/core/BreakPlacementTest.java index 05da5bc..61ba02b 100644 --- a/src/test/java/org/apache/freemarker/core/BreakPlacementTest.java +++ b/src/test/java/org/apache/freemarker/core/BreakPlacementTest.java @@ -50,13 +50,7 @@ public class BreakPlacementTest extends TemplateTest { assertErrorContains("<#if false><#break></#if>", BREAK_NESTING_ERROR_MESSAGE_PART); assertErrorContains("<#list xs><#break></#list>", BREAK_NESTING_ERROR_MESSAGE_PART); assertErrorContains("<#list 1..2 as x>${x}<#else><#break></#list>", BREAK_NESTING_ERROR_MESSAGE_PART); + assertErrorContains("<#list 1..2 as x>${x}<#macro m><#break></#macro></#list>", BREAK_NESTING_ERROR_MESSAGE_PART); } - @Test - public void testInvalidPlacementInsideMacro() throws IOException, TemplateException { - final String ftl = "<#list 1..2 as x>${x}<#macro m><#break></#macro></#list>"; - getConfiguration().setIncompatibleImprovements(Configuration.VERSION_3_0_0); - assertErrorContains(ftl, BREAK_NESTING_ERROR_MESSAGE_PART); - } - } http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/7d61a45d/src/test/java/org/apache/freemarker/core/CamelCaseTest.java ---------------------------------------------------------------------- diff --git a/src/test/java/org/apache/freemarker/core/CamelCaseTest.java b/src/test/java/org/apache/freemarker/core/CamelCaseTest.java index 7c07127..95572ad 100644 --- a/src/test/java/org/apache/freemarker/core/CamelCaseTest.java +++ b/src/test/java/org/apache/freemarker/core/CamelCaseTest.java @@ -31,15 +31,18 @@ import org.apache.freemarker.core.outputformat.impl.HTMLOutputFormat; import org.apache.freemarker.core.outputformat.impl.UndefinedOutputFormat; import org.apache.freemarker.core.util._StringUtil; import org.apache.freemarker.test.TemplateTest; +import org.apache.freemarker.test.TestConfigurationBuilder; import org.junit.Test; public class CamelCaseTest extends TemplateTest { @Test public void camelCaseSpecialVars() throws IOException, TemplateException { - getConfiguration().setOutputEncoding(StandardCharsets.UTF_8); - getConfiguration().setURLEscapingCharset(StandardCharsets.ISO_8859_1); - getConfiguration().setLocale(Locale.GERMANY); + setConfiguration(new TestConfigurationBuilder() + .outputEncoding(StandardCharsets.UTF_8) + .urlEscapingCharset(StandardCharsets.ISO_8859_1) + .locale(Locale.GERMANY) + .build()); assertOutput("${.dataModel?isHash?c}", "true"); assertOutput("${.data_model?is_hash?c}", "true"); assertOutput("${.localeObject.toString()}", "de_DE"); @@ -69,10 +72,11 @@ public class CamelCaseTest extends TemplateTest { assertErrorContains("<#if x><#elseIf y></#if>${.foo}", "dataModel", "\\!data_model"); assertErrorContains("<#if x><#elseif y></#if>${.foo}", "data_model", "\\!dataModel"); - - getConfiguration().setNamingConvention(Configuration.CAMEL_CASE_NAMING_CONVENTION); + + setConfigurationToCamelCaseNamingConvention(); assertErrorContains("${.foo}", "dataModel", "\\!data_model"); - getConfiguration().setNamingConvention(Configuration.LEGACY_NAMING_CONVENTION); + + setConfigurationToLegacyCaseNamingConvention(); assertErrorContains("${.foo}", "data_model", "\\!dataModel"); } @@ -87,8 +91,6 @@ public class CamelCaseTest extends TemplateTest { @Test public void camelCaseFtlHeaderParameters() throws IOException, TemplateException { - getConfiguration().setOutputEncoding(StandardCharsets.UTF_8); - assertOutput( "<#ftl " + "stripWhitespace=false " @@ -116,16 +118,25 @@ public class CamelCaseTest extends TemplateTest { assertErrorContains("<#ftl strip_whitespace=true stripText=true>", "naming convention"); assertErrorContains("<#ftl stripWhitespace=true>${.foo_bar}", "naming convention"); assertErrorContains("<#ftl strip_whitespace=true>${.fooBar}", "naming convention"); - - getConfiguration().setNamingConvention(Configuration.CAMEL_CASE_NAMING_CONVENTION); + + setConfiguration(new TestConfigurationBuilder() + .namingConvention(ParsingConfiguration.CAMEL_CASE_NAMING_CONVENTION) + .outputEncoding(StandardCharsets.UTF_8) + .build()); assertErrorContains("<#ftl strip_whitespace=true>", "naming convention"); assertOutput("<#ftl stripWhitespace=true>${.outputEncoding}", StandardCharsets.UTF_8.name()); - getConfiguration().setNamingConvention(Configuration.LEGACY_NAMING_CONVENTION); + setConfiguration(new TestConfigurationBuilder() + .namingConvention(ParsingConfiguration.LEGACY_NAMING_CONVENTION) + .outputEncoding(StandardCharsets.UTF_8) + .build()); assertErrorContains("<#ftl stripWhitespace=true>", "naming convention"); assertOutput("<#ftl strip_whitespace=true>${.output_encoding}", StandardCharsets.UTF_8.name()); - getConfiguration().setNamingConvention(Configuration.AUTO_DETECT_NAMING_CONVENTION); + setConfiguration(new TestConfigurationBuilder() + .namingConvention(ParsingConfiguration.AUTO_DETECT_NAMING_CONVENTION) + .outputEncoding(StandardCharsets.UTF_8) + .build()); assertOutput("<#ftl stripWhitespace=true>${.outputEncoding}", StandardCharsets.UTF_8.name()); assertOutput("<#ftl encoding='iso-8859-1' stripWhitespace=true>${.outputEncoding}", StandardCharsets.UTF_8.name()); assertOutput("<#ftl stripWhitespace=true encoding='iso-8859-1'>${.outputEncoding}", StandardCharsets.UTF_8.name()); @@ -143,9 +154,10 @@ public class CamelCaseTest extends TemplateTest { assertErrorContains("<#if x><#elseIf y></#if><#setting foo=1>", "booleanFormat", "\\!boolean_format"); assertErrorContains("<#if x><#elseif y></#if><#setting foo=1>", "boolean_format", "\\!booleanFormat"); - getConfiguration().setNamingConvention(Configuration.CAMEL_CASE_NAMING_CONVENTION); + setConfigurationToCamelCaseNamingConvention(); assertErrorContains("<#setting foo=1>", "booleanFormat", "\\!boolean_format"); - getConfiguration().setNamingConvention(Configuration.LEGACY_NAMING_CONVENTION); + + setConfigurationToLegacyCaseNamingConvention(); assertErrorContains("<#setting foo=1>", "boolean_format", "\\!booleanFormat"); } @@ -175,8 +187,8 @@ public class CamelCaseTest extends TemplateTest { @Test public void stringLiteralInterpolation() throws IOException, TemplateException { - assertEquals(Configuration.AUTO_DETECT_NAMING_CONVENTION, getConfiguration().getNamingConvention()); - getConfiguration().setSharedVariable("x", "x"); + assertEquals(ParsingConfiguration.AUTO_DETECT_NAMING_CONVENTION, getConfiguration().getNamingConvention()); + addToDataModel("x", "x"); assertOutput("${'-${x?upperCase}-'} ${x?upperCase}", "-X- X"); assertOutput("${x?upperCase} ${'-${x?upperCase}-'}", "X -X-"); @@ -191,13 +203,13 @@ public class CamelCaseTest extends TemplateTest { "naming convention", "camel", "upper_case"); assertErrorContains("${x?upperCase} ${'-${x?upper_case}-'}", "naming convention", "camel", "upper_case"); - - getConfiguration().setNamingConvention(Configuration.CAMEL_CASE_NAMING_CONVENTION); + + setConfigurationToCamelCaseNamingConvention(); assertOutput("${'-${x?upperCase}-'} ${x?upperCase}", "-X- X"); assertErrorContains("${'-${x?upper_case}-'}", "naming convention", "camel", "upper_case", "\\!detection"); - - getConfiguration().setNamingConvention(Configuration.LEGACY_NAMING_CONVENTION); + + setConfigurationToLegacyCaseNamingConvention(); assertOutput("${'-${x?upper_case}-'} ${x?upper_case}", "-X- X"); assertErrorContains("${'-${x?upperCase}-'}", "naming convention", "legacy", "upperCase", "\\!detection"); @@ -205,7 +217,7 @@ public class CamelCaseTest extends TemplateTest { @Test public void evalAndInterpret() throws IOException, TemplateException { - assertEquals(Configuration.AUTO_DETECT_NAMING_CONVENTION, getConfiguration().getNamingConvention()); + assertEquals(ParsingConfiguration.AUTO_DETECT_NAMING_CONVENTION, getConfiguration().getNamingConvention()); // The naming convention detected doesn't affect the enclosing template's naming convention. // - ?eval: assertOutput("${\"'x'?upperCase\"?eval}${'x'?upper_case}", "XX"); @@ -221,7 +233,7 @@ public class CamelCaseTest extends TemplateTest { "naming convention", "camel", "upperCase", "is_string", "line 2", "line 3"); // Will be inherited by ?eval-ed/?interpreted fragments: - getConfiguration().setNamingConvention(Configuration.CAMEL_CASE_NAMING_CONVENTION); + setConfigurationToCamelCaseNamingConvention(); // - ?eval: assertErrorContains("${\"'x'?upper_case\"?eval}", "naming convention", "camel", "upper_case"); assertOutput("${\"'x'?upperCase\"?eval}", "X"); @@ -230,7 +242,7 @@ public class CamelCaseTest extends TemplateTest { assertOutput("<@r\"${'x'?upperCase}\"?interpret />", "X"); // Again, will be inherited by ?eval-ed/?interpreted fragments: - getConfiguration().setNamingConvention(Configuration.LEGACY_NAMING_CONVENTION); + setConfigurationToLegacyCaseNamingConvention(); // - ?eval: assertErrorContains("${\"'x'?upperCase\"?eval}", "naming convention", "legacy", "upperCase"); assertOutput("${\"'x'?upper_case\"?eval}", "X"); @@ -238,7 +250,13 @@ public class CamelCaseTest extends TemplateTest { assertErrorContains("<@r\"${'x'?upperCase}\"?interpret />", "naming convention", "legacy", "upperCase"); assertOutput("<@r\"${'x'?upper_case}\"?interpret />", "X"); } - + + private void setConfigurationToLegacyCaseNamingConvention() { + setConfiguration(new TestConfigurationBuilder() + .namingConvention(ParsingConfiguration.LEGACY_NAMING_CONVENTION) + .build()); + } + @Test public void camelCaseBuiltInErrorMessage() throws IOException, TemplateException { assertErrorContains("${'x'?upperCasw}", "upperCase", "\\!upper_case"); @@ -248,13 +266,19 @@ public class CamelCaseTest extends TemplateTest { assertErrorContains("<#if x><#elseIf y></#if> ${'x'?foo}", "upperCase", "\\!upper_case"); assertErrorContains("<#if x><#elseif y></#if>${'x'?foo}", "upper_case", "\\!upperCase"); - - getConfiguration().setNamingConvention(Configuration.CAMEL_CASE_NAMING_CONVENTION); + + setConfigurationToCamelCaseNamingConvention(); assertErrorContains("${'x'?foo}", "upperCase", "\\!upper_case"); - getConfiguration().setNamingConvention(Configuration.LEGACY_NAMING_CONVENTION); + setConfigurationToLegacyCaseNamingConvention(); assertErrorContains("${'x'?foo}", "upper_case", "\\!upperCase"); } - + + private void setConfigurationToCamelCaseNamingConvention() { + setConfiguration(new TestConfigurationBuilder() + .namingConvention(ParsingConfiguration.CAMEL_CASE_NAMING_CONVENTION) + .build()); + } + @Test public void builtInsHasBothNamingStyle() throws IOException, TemplateException { assertContainsBothNamingStyles(getConfiguration().getSupportedBuiltInNames(), new NamePairAssertion() { @@ -273,7 +297,7 @@ public class CamelCaseTest extends TemplateTest { private void assertContainsBothNamingStyles(Set<String> names, NamePairAssertion namePairAssertion) { Set<String> underscoredNamesWithCamelCasePair = new HashSet<>(); for (String name : names) { - if (_StringUtil.getIdentifierNamingConvention(name) == Configuration.CAMEL_CASE_NAMING_CONVENTION) { + if (_StringUtil.getIdentifierNamingConvention(name) == ParsingConfiguration.CAMEL_CASE_NAMING_CONVENTION) { String underscoredName = correctIsoBIExceptions(_StringUtil.camelCaseToUnderscored(name)); assertTrue( "Missing underscored variation \"" + underscoredName + "\" for \"" + name + "\".", @@ -284,7 +308,7 @@ public class CamelCaseTest extends TemplateTest { } } for (String name : names) { - if (_StringUtil.getIdentifierNamingConvention(name) == Configuration.LEGACY_NAMING_CONVENTION) { + if (_StringUtil.getIdentifierNamingConvention(name) == ParsingConfiguration.LEGACY_NAMING_CONVENTION) { assertTrue("Missing camel case variation for \"" + name + "\".", underscoredNamesWithCamelCasePair.contains(name)); } @@ -298,7 +322,9 @@ public class CamelCaseTest extends TemplateTest { @Test public void camelCaseDirectives() throws IOException, TemplateException { camelCaseDirectives(false); - getConfiguration().setTagSyntax(Configuration.AUTO_DETECT_TAG_SYNTAX); + setConfiguration(new TestConfigurationBuilder() + .tagSyntax(ParsingConfiguration.AUTO_DETECT_TAG_SYNTAX) + .build()); camelCaseDirectives(true); } @@ -338,12 +364,13 @@ public class CamelCaseTest extends TemplateTest { } private void explicitNamingConvention(boolean squared) throws IOException, TemplateException { - if (squared) { - getConfiguration().setTagSyntax(Configuration.AUTO_DETECT_TAG_SYNTAX); - } - - getConfiguration().setNamingConvention(Configuration.CAMEL_CASE_NAMING_CONVENTION); - + int tagSyntax = squared ? ParsingConfiguration.AUTO_DETECT_TAG_SYNTAX + : ParsingConfiguration.ANGLE_BRACKET_TAG_SYNTAX; + setConfiguration(new TestConfigurationBuilder() + .tagSyntax(tagSyntax) + .namingConvention(ParsingConfiguration.CAMEL_CASE_NAMING_CONVENTION) + .build()); + assertErrorContains( squared("<#if true>t<#elseif false>f</#if>", squared), "naming convention", "camel", "#elseif"); @@ -366,9 +393,12 @@ public class CamelCaseTest extends TemplateTest { "1"); // --- - - getConfiguration().setNamingConvention(Configuration.LEGACY_NAMING_CONVENTION); - + + setConfiguration(new TestConfigurationBuilder() + .tagSyntax(tagSyntax) + .namingConvention(ParsingConfiguration.LEGACY_NAMING_CONVENTION) + .build()); + assertErrorContains( squared("<#if true>t<#elseIf false>f</#if>", squared), "naming convention", "legacy", "#elseIf"); http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/7d61a45d/src/test/java/org/apache/freemarker/core/CanonicalFormTest.java ---------------------------------------------------------------------- diff --git a/src/test/java/org/apache/freemarker/core/CanonicalFormTest.java b/src/test/java/org/apache/freemarker/core/CanonicalFormTest.java index 3218cd6..c78c90e 100644 --- a/src/test/java/org/apache/freemarker/core/CanonicalFormTest.java +++ b/src/test/java/org/apache/freemarker/core/CanonicalFormTest.java @@ -24,6 +24,7 @@ import java.io.StringWriter; import org.apache.freemarker.core.templateresolver.impl.ClassTemplateLoader; import org.apache.freemarker.test.CopyrightCommentRemoverTemplateLoader; +import org.apache.freemarker.test.TestConfigurationBuilder; import org.apache.freemarker.test.util.FileTestCase; public class CanonicalFormTest extends FileTestCase { @@ -54,13 +55,13 @@ public class CanonicalFormTest extends FileTestCase { private void assertCanonicalFormOf(String ftlFileName) throws IOException { - Configuration cfg = new Configuration(Configuration.VERSION_3_0_0); - cfg.setTemplateLoader( - new CopyrightCommentRemoverTemplateLoader( - new ClassTemplateLoader(CanonicalFormTest.class, ""))); + Configuration cfg = new TestConfigurationBuilder() + .templateLoader( + new CopyrightCommentRemoverTemplateLoader( + new ClassTemplateLoader(CanonicalFormTest.class, ""))) + .build(); StringWriter sw = new StringWriter(); cfg.getTemplate(ftlFileName).dump(sw); - assertExpectedFileEqualsString(ftlFileName + ".out", sw.toString()); } http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/7d61a45d/src/test/java/org/apache/freemarker/core/CoercionToTextualTest.java ---------------------------------------------------------------------- diff --git a/src/test/java/org/apache/freemarker/core/CoercionToTextualTest.java b/src/test/java/org/apache/freemarker/core/CoercionToTextualTest.java index 83f4ba5..c8a3335 100644 --- a/src/test/java/org/apache/freemarker/core/CoercionToTextualTest.java +++ b/src/test/java/org/apache/freemarker/core/CoercionToTextualTest.java @@ -29,6 +29,7 @@ import org.apache.freemarker.core.outputformat.impl.HTMLOutputFormat; import org.apache.freemarker.core.userpkg.HTMLISOTemplateDateFormatFactory; import org.apache.freemarker.core.userpkg.PrintfGTemplateNumberFormatFactory; import org.apache.freemarker.test.TemplateTest; +import org.apache.freemarker.test.TestConfigurationBuilder; import org.junit.Before; import org.junit.Test; @@ -52,11 +53,11 @@ public class CoercionToTextualTest extends TemplateTest { @Test public void testEscBuiltin() throws IOException, TemplateException { - Configuration cfg = getConfiguration(); - cfg.setOutputFormat(HTMLOutputFormat.INSTANCE); - cfg.setAutoEscapingPolicy(Configuration.DISABLE_AUTO_ESCAPING_POLICY); - cfg.setBooleanFormat("<y>,<n>"); - + setConfiguration(createDefaultConfigurationBuilder() + .outputFormat(HTMLOutputFormat.INSTANCE) + .autoEscapingPolicy(ParsingConfiguration.DISABLE_AUTO_ESCAPING_POLICY) + .booleanFormat("<y>,<n>") + .build()); assertOutput("${'a<b'?esc}", "a<b"); assertOutput("${n?string?esc}", "1.50E+03"); assertOutput("${n?esc}", "1.50*10<sup>3</sup>"); @@ -117,16 +118,23 @@ public class CoercionToTextualTest extends TemplateTest { assertOutput("${'&' + b}", "&y"); assertOutput("${'&' + m}", "&<p>M</p>"); } - + + @Override + protected Configuration createDefaultConfiguration() throws Exception { + return createDefaultConfigurationBuilder().build(); + } + + private TestConfigurationBuilder createDefaultConfigurationBuilder() { + return new TestConfigurationBuilder() + .customNumberFormats(Collections.singletonMap("G", PrintfGTemplateNumberFormatFactory.INSTANCE)) + .customDateFormats(Collections.singletonMap("HI", HTMLISOTemplateDateFormatFactory.INSTANCE)) + .numberFormat("@G 3") + .dateTimeFormat("@HI") + .booleanFormat("y,n"); + } + @Before public void setup() throws TemplateModelException { - Configuration cfg = getConfiguration(); - cfg.setCustomNumberFormats(Collections.singletonMap("G", PrintfGTemplateNumberFormatFactory.INSTANCE)); - cfg.setCustomDateFormats(Collections.singletonMap("HI", HTMLISOTemplateDateFormatFactory.INSTANCE)); - cfg.setNumberFormat("@G 3"); - cfg.setDateTimeFormat("@HI"); - cfg.setBooleanFormat("y,n"); - addToDataModel("s", "abc"); addToDataModel("n", 1500); addToDataModel("dt", TM); http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/7d61a45d/src/test/java/org/apache/freemarker/core/ConfigurableTest.java ---------------------------------------------------------------------- diff --git a/src/test/java/org/apache/freemarker/core/ConfigurableTest.java b/src/test/java/org/apache/freemarker/core/ConfigurableTest.java index bff5dc0..ebcc465 100644 --- a/src/test/java/org/apache/freemarker/core/ConfigurableTest.java +++ b/src/test/java/org/apache/freemarker/core/ConfigurableTest.java @@ -96,7 +96,7 @@ public class ConfigurableTest { String fieldName = field.getName(); if (fieldName.endsWith("_KEY")) { String keyFieldValue = (String) field.get(null); - assertNotEquals(Configuration.CAMEL_CASE_NAMING_CONVENTION, + assertNotEquals(ParsingConfiguration.CAMEL_CASE_NAMING_CONVENTION, _StringUtil.getIdentifierNamingConvention(keyFieldValue)); assertEquals(fieldName.substring(0, fieldName.length() - 4).toLowerCase(), keyFieldValue); @@ -109,7 +109,7 @@ public class ConfigurableTest { try { String keyCCFieldValue = (String) confClass.getField(fieldName + "_CAMEL_CASE").get(null); - assertNotEquals(Configuration.LEGACY_NAMING_CONVENTION, + assertNotEquals(ParsingConfiguration.LEGACY_NAMING_CONVENTION, _StringUtil.getIdentifierNamingConvention(keyCCFieldValue)); assertEquals(keyFieldValue, _StringUtil.camelCaseToUnderscored(keyCCFieldValue)); } catch (NoSuchFieldException e) {
