Browse Source

FreeMarkerConfigurationFactory properly supports TemplateLoaders when recreating Configurations

Issue: SPR-9389
3.1.x
Juergen Hoeller 13 years ago
parent
commit
0ed1a21073
  1. 51
      org.springframework.context.support/src/main/java/org/springframework/ui/freemarker/FreeMarkerConfigurationFactory.java

51
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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with 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.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Properties; import java.util.Properties;
@ -47,12 +48,12 @@ import org.springframework.util.CollectionUtils;
* <p>The optional "configLocation" property sets the location of a FreeMarker * <p>The optional "configLocation" property sets the location of a FreeMarker
* properties file, within the current application. FreeMarker properties can be * properties file, within the current application. FreeMarker properties can be
* overridden via "freemarkerSettings". All of these properties will be set by * overridden via "freemarkerSettings". All of these properties will be set by
* calling FreeMarker's <code>Configuration.setSettings()</code> method and are * calling FreeMarker's {@code Configuration.setSettings()} method and are
* subject to constraints set by FreeMarker. * subject to constraints set by FreeMarker.
* *
* <p>The "freemarkerVariables" property can be used to specify a Map of * <p>The "freemarkerVariables" property can be used to specify a Map of
* shared variables that will be applied to the Configuration via the * shared variables that will be applied to the Configuration via the
* <code>setAllSharedVariables()</code> method. Like <code>setSettings()</code>, * {@code setAllSharedVariables()} method. Like {@code setSettings()},
* these entries are subject to FreeMarker constraints. * these entries are subject to FreeMarker constraints.
* *
* <p>The simplest way to use this class is to specify a "templateLoaderPath"; * <p>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 * Set properties that contain well-known FreeMarker keys which will be
* passed to FreeMarker's <code>Configuration.setSettings</code> method. * passed to FreeMarker's {@code Configuration.setSettings} method.
* @see freemarker.template.Configuration#setSettings * @see freemarker.template.Configuration#setSettings
*/ */
public void setFreemarkerSettings(Properties settings) { 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 * Set a Map that contains well-known FreeMarker objects which will be passed
* to FreeMarker's <code>Configuration.setAllSharedVariables()</code> method. * to FreeMarker's {@code Configuration.setAllSharedVariables()} method.
* @see freemarker.template.Configuration#setAllSharedVariables * @see freemarker.template.Configuration#setAllSharedVariables
*/ */
public void setFreemarkerVariables(Map<String, Object> variables) { public void setFreemarkerVariables(Map<String, Object> variables) {
@ -138,7 +139,7 @@ public class FreeMarkerConfigurationFactory {
} }
/** /**
* Set a List of <code>TemplateLoader<code>s 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 * for templates. For example, one or more custom loaders such as database
* loaders could be configured and injected here. * loaders could be configured and injected here.
* @deprecated as of Spring 2.0.1, in favor of the "preTemplateLoaders" * @deprecated as of Spring 2.0.1, in favor of the "preTemplateLoaders"
@ -147,14 +148,14 @@ public class FreeMarkerConfigurationFactory {
* @see #setPostTemplateLoaders * @see #setPostTemplateLoaders
*/ */
@Deprecated @Deprecated
public void setTemplateLoaders(TemplateLoader[] templateLoaders) { public void setTemplateLoaders(TemplateLoader... templateLoaders) {
if (templateLoaders != null) { if (templateLoaders != null) {
this.templateLoaders.addAll(Arrays.asList(templateLoaders)); this.templateLoaders.addAll(Arrays.asList(templateLoaders));
} }
} }
/** /**
* Set a List of <code>TemplateLoader<code>s 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 * for templates. For example, one or more custom loaders such as database
* loaders could be configured and injected here. * loaders could be configured and injected here.
* <p>The {@link TemplateLoader TemplateLoaders} specified here will be * <p>The {@link TemplateLoader TemplateLoaders} specified here will be
@ -164,12 +165,12 @@ public class FreeMarkerConfigurationFactory {
* @see #setTemplateLoaderPaths * @see #setTemplateLoaderPaths
* @see #postProcessTemplateLoaders * @see #postProcessTemplateLoaders
*/ */
public void setPreTemplateLoaders(TemplateLoader[] preTemplateLoaders) { public void setPreTemplateLoaders(TemplateLoader... preTemplateLoaders) {
this.preTemplateLoaders = Arrays.asList(preTemplateLoaders); this.preTemplateLoaders = Arrays.asList(preTemplateLoaders);
} }
/** /**
* Set a List of <code>TemplateLoader<code>s 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 * for templates. For example, one or more custom loaders such as database
* loaders can be configured. * loaders can be configured.
* <p>The {@link TemplateLoader TemplateLoaders} specified here will be * <p>The {@link TemplateLoader TemplateLoaders} specified here will be
@ -179,7 +180,7 @@ public class FreeMarkerConfigurationFactory {
* @see #setTemplateLoaderPaths * @see #setTemplateLoaderPaths
* @see #postProcessTemplateLoaders * @see #postProcessTemplateLoaders
*/ */
public void setPostTemplateLoaders(TemplateLoader[] postTemplateLoaders) { public void setPostTemplateLoaders(TemplateLoader... postTemplateLoaders) {
this.postTemplateLoaders = Arrays.asList(postTemplateLoaders); this.postTemplateLoaders = Arrays.asList(postTemplateLoaders);
} }
@ -198,20 +199,20 @@ public class FreeMarkerConfigurationFactory {
* pseudo URLs are supported, as understood by ResourceEditor. Allows for * pseudo URLs are supported, as understood by ResourceEditor. Allows for
* relative paths when running in an ApplicationContext. * relative paths when running in an ApplicationContext.
* <p>Will define a path for the default FreeMarker template loader. * <p>Will define a path for the default FreeMarker template loader.
* If a specified resource cannot be resolved to a <code>java.io.File</code>, * If a specified resource cannot be resolved to a {@code java.io.File},
* a generic SpringTemplateLoader will be used, without modification detection. * a generic SpringTemplateLoader will be used, without modification detection.
* <p>To enforce the use of SpringTemplateLoader, i.e. to not resolve a path * <p>To enforce the use of SpringTemplateLoader, i.e. to not resolve a path
* as file system resource in any case, turn off the "preferFileSystemAccess" * as file system resource in any case, turn off the "preferFileSystemAccess"
* flag. See the latter's javadoc for details. * flag. See the latter's javadoc for details.
* <p>If you wish to specify your own list of TemplateLoaders, do not set this * <p>If you wish to specify your own list of TemplateLoaders, do not set this
* property and instead use <code>setTemplateLoaders(List templateLoaders)</code> * property and instead use {@code setTemplateLoaders(List templateLoaders)}
* @see org.springframework.core.io.ResourceEditor * @see org.springframework.core.io.ResourceEditor
* @see org.springframework.context.ApplicationContext#getResource * @see org.springframework.context.ApplicationContext#getResource
* @see freemarker.template.Configuration#setDirectoryForTemplateLoading * @see freemarker.template.Configuration#setDirectoryForTemplateLoading
* @see SpringTemplateLoader * @see SpringTemplateLoader
* @see #setTemplateLoaders * @see #setTemplateLoaders
*/ */
public void setTemplateLoaderPaths(String[] templateLoaderPaths) { public void setTemplateLoaderPaths(String... templateLoaderPaths) {
this.templateLoaderPaths = templateLoaderPaths; this.templateLoaderPaths = templateLoaderPaths;
} }
@ -229,7 +230,7 @@ public class FreeMarkerConfigurationFactory {
* Return the Spring ResourceLoader to use for loading FreeMarker template files. * Return the Spring ResourceLoader to use for loading FreeMarker template files.
*/ */
protected ResourceLoader getResourceLoader() { 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. * Return whether to prefer file system access for template loading.
*/ */
protected boolean isPreferFileSystemAccess() { protected boolean isPreferFileSystemAccess() {
return preferFileSystemAccess; return this.preferFileSystemAccess;
} }
@ -293,25 +294,27 @@ public class FreeMarkerConfigurationFactory {
config.setDefaultEncoding(this.defaultEncoding); config.setDefaultEncoding(this.defaultEncoding);
} }
List<TemplateLoader> templateLoaders = new LinkedList<TemplateLoader>(this.templateLoaders);
// Register template loaders that are supposed to kick in early. // Register template loaders that are supposed to kick in early.
if (this.preTemplateLoaders != null) { if (this.preTemplateLoaders != null) {
this.templateLoaders.addAll(this.preTemplateLoaders); templateLoaders.addAll(this.preTemplateLoaders);
} }
// Register default template loaders. // Register default template loaders.
if (this.templateLoaderPaths != null) { if (this.templateLoaderPaths != null) {
for (String path : this.templateLoaderPaths) { 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. // Register template loaders that are supposed to kick in late.
if (this.postTemplateLoaders != null) { 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) { if (loader != null) {
config.setTemplateLoader(loader); config.setTemplateLoader(loader);
} }
@ -323,7 +326,7 @@ public class FreeMarkerConfigurationFactory {
/** /**
* Return a new Configuration object. Subclasses can override this for * Return a new Configuration object. Subclasses can override this for
* custom initialization, or for using a mock object for testing. * custom initialization, or for using a mock object for testing.
* <p>Called by <code>createConfiguration()</code>. * <p>Called by {@code createConfiguration()}.
* @return the Configuration object * @return the Configuration object
* @throws IOException if a config file wasn't found * @throws IOException if a config file wasn't found
* @throws TemplateException on FreeMarker initialization failure * @throws TemplateException on FreeMarker initialization failure
@ -374,7 +377,7 @@ public class FreeMarkerConfigurationFactory {
* To be overridden by subclasses that want to to register custom * To be overridden by subclasses that want to to register custom
* TemplateLoader instances after this factory created its default * TemplateLoader instances after this factory created its default
* template loaders. * template loaders.
* <p>Called by <code>createConfiguration()</code>. Note that specified * <p>Called by {@code createConfiguration()}. Note that specified
* "postTemplateLoaders" will be registered <i>after</i> any loaders * "postTemplateLoaders" will be registered <i>after</i> any loaders
* registered by this callback; as a consequence, they are are <i>not</i> * registered by this callback; as a consequence, they are are <i>not</i>
* included in the given List. * included in the given List.
@ -411,7 +414,7 @@ public class FreeMarkerConfigurationFactory {
* To be overridden by subclasses that want to to perform custom * To be overridden by subclasses that want to to perform custom
* post-processing of the Configuration object after this factory * post-processing of the Configuration object after this factory
* performed its default initialization. * performed its default initialization.
* <p>Called by <code>createConfiguration()</code>. * <p>Called by {@code createConfiguration()}.
* @param config the current Configuration object * @param config the current Configuration object
* @throws IOException if a config file wasn't found * @throws IOException if a config file wasn't found
* @throws TemplateException on FreeMarker initialization failure * @throws TemplateException on FreeMarker initialization failure

Loading…
Cancel
Save