/* * Copyright 2002-2005 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. * 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.springmodules.template.engine.freemarker; import java.io.IOException; import java.io.InputStreamReader; import java.io.Reader; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.Properties; import freemarker.template.Configuration; import freemarker.template.ObjectWrapper; import freemarker.template.TemplateException; import org.springframework.beans.factory.InitializingBean; import org.springframework.core.io.DefaultResourceLoader; import org.springframework.core.io.Resource; import org.springframework.core.io.ResourceLoader; import org.springframework.util.Assert; import org.springmodules.template.Template; import org.springmodules.template.TemplateCreationException; import org.springmodules.template.engine.AbstractTemplateEngine; /** * Represents the freemarker template engine. * * @author Uri Boness */ public class FreemarkerTemplateEngine extends AbstractTemplateEngine implements InitializingBean { private Properties settings; private Map sharedVariables; private ObjectWrapper objectWrapper; private Configuration configuration; private ResourceLoader resourceLoader; /** * Constructs a new FreemarkerTemplateEngine. The engine uses the default settings of freemarker engine and * {@link DefaultResourceLoader} as the resource loader that is used to load all template resources. */ public FreemarkerTemplateEngine() { this(new DefaultResourceLoader()); } /** * Constructs a new FreemarkerTemplateEngine with a given resource loader. The engine uses the default settings of * freemarker engine. * * @param resourceLoader The resource loader this engine will use to load all template resources. */ public FreemarkerTemplateEngine(ResourceLoader resourceLoader) { this(resourceLoader, null, new HashMap()); } /** * Constructs a new FreemarkerTemplateEngine with a given resource loader, settings, and shared variables. * * @param resourceLoader The resource loader this engine will use to load all template resources. * @param settings freemarker settings to configure the freemarker engine. * @param sharedVariables Variables that are shared between all template created/managed by this engine. */ public FreemarkerTemplateEngine(ResourceLoader resourceLoader, Properties settings, Map sharedVariables) { this.resourceLoader = resourceLoader; this.sharedVariables = sharedVariables; this.settings = settings; } /** * @see org.springmodules.template.TemplateEngine#createTemplate(org.springframework.core.io.Resource, String) */ public Template createTemplate(Resource resource, String encoding) { try { Reader reader = new InputStreamReader(resource.getInputStream()); String name = resource.getFilename(); return new FreemarkerTemplate(createFreemarkerTemplate(name, reader, configuration)); } catch (IOException ioe) { throw new TemplateCreationException( "Could not create freemarker template from resource '" + resource.getDescription() + "'", ioe); } } public void afterPropertiesSet() throws Exception { Assert.notNull(resourceLoader, "Required properties 'resourceLoader' is not set"); configuration = createConfiguration(resourceLoader, settings, sharedVariables, objectWrapper); } //================================================== Setter/Getter ================================================= /** * Returns the extra settings set for this freemarker engine. * * @return The extra settings set for this freemarker engine. */ public Properties getSettings() { return settings; } /** * Sets extra settings for this freemarker engine. * * @param settings The extra settings for this freemarker engine. * @see Configuration#setSettings(java.util.Properties) */ public void setSettings(Properties settings) { this.settings = settings; } /** * Sets the {@link ResourceLoader resource loader} that this engine will use to load the templates. * * @param resourceLoader The resource loader that will be used by this engine to load the templates. */ public void setResourceLoader(ResourceLoader resourceLoader) { this.resourceLoader = resourceLoader; } /** * Sets shared variables for the freemarker engine. Shared variable are managed by freemarker and are shared * among all templates. * * @param sharedVariables The variables to be shared by all templates. */ public void setSharedVariables(Map sharedVariables) { this.sharedVariables = sharedVariables; } /** * Sets the object wrapper the freemarker engine will use to access the objects in the model. * * @param objectWrapper The object wrapper the freemarker engine will use to access the objects in the model. */ public void setObjectWrapper(ObjectWrapper objectWrapper) { this.objectWrapper = objectWrapper; } //================================================== Helper Methods ================================================ protected static freemarker.template.Template createFreemarkerTemplate( String name, Reader reader, Configuration configuration) throws IOException { return new freemarker.template.Template(name, reader, configuration); } /** * Creates a freemarker configuration with the given resource loader, freemarker settings, and shared variables. * * @param resourceLoader The resource loader that will be used to load all template resources. * @param settings The freemarker settings. Can be <code>null</code> * @param sharedVariables Variables shared by all templates created/managed by this engine. * @return The created configuration. * @throws TemplateException thrown when configuration construction fails. */ protected static Configuration createConfiguration( ResourceLoader resourceLoader, Properties settings, Map sharedVariables, ObjectWrapper objectWrapper) throws TemplateException { ResourceLoaderTemplateLoader templateLoader = new ResourceLoaderTemplateLoader(resourceLoader); Configuration configuration = new Configuration(); configuration.setTemplateLoader(templateLoader); for (Iterator vars = sharedVariables.entrySet().iterator(); vars.hasNext();) { Map.Entry var = (Map.Entry)vars.next(); configuration.setSharedVariable((String)var.getKey(), var.getValue()); } if (settings != null) { configuration.setSettings(settings); } if (objectWrapper != null) { configuration.setObjectWrapper(objectWrapper); } return configuration; } }