From 0ed1a21073f707b64dfaca3c48fa0f6e6633ab62 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Wed, 9 Jan 2013 18:24:54 +0100 Subject: [PATCH] FreeMarkerConfigurationFactory properly supports TemplateLoaders when recreating Configurations Issue: SPR-9389 --- .../FreeMarkerConfigurationFactory.java | 51 ++++++++++--------- 1 file changed, 27 insertions(+), 24 deletions(-) diff --git a/org.springframework.context.support/src/main/java/org/springframework/ui/freemarker/FreeMarkerConfigurationFactory.java b/org.springframework.context.support/src/main/java/org/springframework/ui/freemarker/FreeMarkerConfigurationFactory.java index 2abf6296e2e..027f0f4a6bc 100644 --- a/org.springframework.context.support/src/main/java/org/springframework/ui/freemarker/FreeMarkerConfigurationFactory.java +++ b/org.springframework.context.support/src/main/java/org/springframework/ui/freemarker/FreeMarkerConfigurationFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2010 the original author or authors. + * Copyright 2002-2013 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,6 +20,7 @@ import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; +import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Properties; @@ -47,12 +48,12 @@ import org.springframework.util.CollectionUtils; *

The optional "configLocation" property sets the location of a FreeMarker * properties file, within the current application. FreeMarker properties can be * overridden via "freemarkerSettings". All of these properties will be set by - * calling FreeMarker's Configuration.setSettings() method and are + * calling FreeMarker's {@code Configuration.setSettings()} method and are * subject to constraints set by FreeMarker. * *

The "freemarkerVariables" property can be used to specify a Map of * shared variables that will be applied to the Configuration via the - * setAllSharedVariables() method. Like setSettings(), + * {@code setAllSharedVariables()} method. Like {@code setSettings()}, * these entries are subject to FreeMarker constraints. * *

The simplest way to use this class is to specify a "templateLoaderPath"; @@ -109,7 +110,7 @@ public class FreeMarkerConfigurationFactory { /** * Set properties that contain well-known FreeMarker keys which will be - * passed to FreeMarker's Configuration.setSettings method. + * passed to FreeMarker's {@code Configuration.setSettings} method. * @see freemarker.template.Configuration#setSettings */ public void setFreemarkerSettings(Properties settings) { @@ -118,7 +119,7 @@ public class FreeMarkerConfigurationFactory { /** * Set a Map that contains well-known FreeMarker objects which will be passed - * to FreeMarker's Configuration.setAllSharedVariables() method. + * to FreeMarker's {@code Configuration.setAllSharedVariables()} method. * @see freemarker.template.Configuration#setAllSharedVariables */ public void setFreemarkerVariables(Map variables) { @@ -138,7 +139,7 @@ public class FreeMarkerConfigurationFactory { } /** - * Set a List of TemplateLoaders that will be used to search + * Set a List of {@code TemplateLoader}s that will be used to search * for templates. For example, one or more custom loaders such as database * loaders could be configured and injected here. * @deprecated as of Spring 2.0.1, in favor of the "preTemplateLoaders" @@ -147,14 +148,14 @@ public class FreeMarkerConfigurationFactory { * @see #setPostTemplateLoaders */ @Deprecated - public void setTemplateLoaders(TemplateLoader[] templateLoaders) { + public void setTemplateLoaders(TemplateLoader... templateLoaders) { if (templateLoaders != null) { this.templateLoaders.addAll(Arrays.asList(templateLoaders)); } } /** - * Set a List of TemplateLoaders that will be used to search + * Set a List of {@code TemplateLoader}s that will be used to search * for templates. For example, one or more custom loaders such as database * loaders could be configured and injected here. *

The {@link TemplateLoader TemplateLoaders} specified here will be @@ -164,12 +165,12 @@ public class FreeMarkerConfigurationFactory { * @see #setTemplateLoaderPaths * @see #postProcessTemplateLoaders */ - public void setPreTemplateLoaders(TemplateLoader[] preTemplateLoaders) { + public void setPreTemplateLoaders(TemplateLoader... preTemplateLoaders) { this.preTemplateLoaders = Arrays.asList(preTemplateLoaders); } /** - * Set a List of TemplateLoaders that will be used to search + * Set a List of {@code TemplateLoader}s that will be used to search * for templates. For example, one or more custom loaders such as database * loaders can be configured. *

The {@link TemplateLoader TemplateLoaders} specified here will be @@ -179,7 +180,7 @@ public class FreeMarkerConfigurationFactory { * @see #setTemplateLoaderPaths * @see #postProcessTemplateLoaders */ - public void setPostTemplateLoaders(TemplateLoader[] postTemplateLoaders) { + public void setPostTemplateLoaders(TemplateLoader... postTemplateLoaders) { this.postTemplateLoaders = Arrays.asList(postTemplateLoaders); } @@ -198,20 +199,20 @@ public class FreeMarkerConfigurationFactory { * pseudo URLs are supported, as understood by ResourceEditor. Allows for * relative paths when running in an ApplicationContext. *

Will define a path for the default FreeMarker template loader. - * If a specified resource cannot be resolved to a java.io.File, + * If a specified resource cannot be resolved to a {@code java.io.File}, * a generic SpringTemplateLoader will be used, without modification detection. *

To enforce the use of SpringTemplateLoader, i.e. to not resolve a path * as file system resource in any case, turn off the "preferFileSystemAccess" * flag. See the latter's javadoc for details. *

If you wish to specify your own list of TemplateLoaders, do not set this - * property and instead use setTemplateLoaders(List templateLoaders) + * property and instead use {@code setTemplateLoaders(List templateLoaders)} * @see org.springframework.core.io.ResourceEditor * @see org.springframework.context.ApplicationContext#getResource * @see freemarker.template.Configuration#setDirectoryForTemplateLoading * @see SpringTemplateLoader * @see #setTemplateLoaders */ - public void setTemplateLoaderPaths(String[] templateLoaderPaths) { + public void setTemplateLoaderPaths(String... templateLoaderPaths) { this.templateLoaderPaths = templateLoaderPaths; } @@ -229,7 +230,7 @@ public class FreeMarkerConfigurationFactory { * Return the Spring ResourceLoader to use for loading FreeMarker template files. */ protected ResourceLoader getResourceLoader() { - return resourceLoader; + return this.resourceLoader; } /** @@ -252,7 +253,7 @@ public class FreeMarkerConfigurationFactory { * Return whether to prefer file system access for template loading. */ protected boolean isPreferFileSystemAccess() { - return preferFileSystemAccess; + return this.preferFileSystemAccess; } @@ -293,25 +294,27 @@ public class FreeMarkerConfigurationFactory { config.setDefaultEncoding(this.defaultEncoding); } + List templateLoaders = new LinkedList(this.templateLoaders); + // Register template loaders that are supposed to kick in early. if (this.preTemplateLoaders != null) { - this.templateLoaders.addAll(this.preTemplateLoaders); + templateLoaders.addAll(this.preTemplateLoaders); } // Register default template loaders. if (this.templateLoaderPaths != null) { for (String path : this.templateLoaderPaths) { - this.templateLoaders.add(getTemplateLoaderForPath(path)); + templateLoaders.add(getTemplateLoaderForPath(path)); } } - postProcessTemplateLoaders(this.templateLoaders); + postProcessTemplateLoaders(templateLoaders); // Register template loaders that are supposed to kick in late. if (this.postTemplateLoaders != null) { - this.templateLoaders.addAll(this.postTemplateLoaders); + templateLoaders.addAll(this.postTemplateLoaders); } - TemplateLoader loader = getAggregateTemplateLoader(this.templateLoaders); + TemplateLoader loader = getAggregateTemplateLoader(templateLoaders); if (loader != null) { config.setTemplateLoader(loader); } @@ -323,7 +326,7 @@ public class FreeMarkerConfigurationFactory { /** * Return a new Configuration object. Subclasses can override this for * custom initialization, or for using a mock object for testing. - *

Called by createConfiguration(). + *

Called by {@code createConfiguration()}. * @return the Configuration object * @throws IOException if a config file wasn't found * @throws TemplateException on FreeMarker initialization failure @@ -374,7 +377,7 @@ public class FreeMarkerConfigurationFactory { * To be overridden by subclasses that want to to register custom * TemplateLoader instances after this factory created its default * template loaders. - *

Called by createConfiguration(). Note that specified + *

Called by {@code createConfiguration()}. Note that specified * "postTemplateLoaders" will be registered after any loaders * registered by this callback; as a consequence, they are are not * included in the given List. @@ -411,7 +414,7 @@ public class FreeMarkerConfigurationFactory { * To be overridden by subclasses that want to to perform custom * post-processing of the Configuration object after this factory * performed its default initialization. - *

Called by createConfiguration(). + *

Called by {@code createConfiguration()}. * @param config the current Configuration object * @throws IOException if a config file wasn't found * @throws TemplateException on FreeMarker initialization failure