001/*
002 * Copyright 2002-2014 the original author or authors.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *      https://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017package org.springframework.ui.freemarker;
018
019import java.io.IOException;
020import java.io.InputStreamReader;
021import java.io.Reader;
022
023import freemarker.cache.TemplateLoader;
024import org.apache.commons.logging.Log;
025import org.apache.commons.logging.LogFactory;
026
027import org.springframework.core.io.Resource;
028import org.springframework.core.io.ResourceLoader;
029
030/**
031 * FreeMarker {@link TemplateLoader} adapter that loads via a Spring {@link ResourceLoader}.
032 * Used by {@link FreeMarkerConfigurationFactory} for any resource loader path that cannot
033 * be resolved to a {@link java.io.File}.
034 *
035 * @author Juergen Hoeller
036 * @since 14.03.2004
037 * @see FreeMarkerConfigurationFactory#setTemplateLoaderPath
038 * @see freemarker.template.Configuration#setDirectoryForTemplateLoading
039 */
040public class SpringTemplateLoader implements TemplateLoader {
041
042        protected final Log logger = LogFactory.getLog(getClass());
043
044        private final ResourceLoader resourceLoader;
045
046        private final String templateLoaderPath;
047
048
049        /**
050         * Create a new SpringTemplateLoader.
051         * @param resourceLoader the Spring ResourceLoader to use
052         * @param templateLoaderPath the template loader path to use
053         */
054        public SpringTemplateLoader(ResourceLoader resourceLoader, String templateLoaderPath) {
055                this.resourceLoader = resourceLoader;
056                if (!templateLoaderPath.endsWith("/")) {
057                        templateLoaderPath += "/";
058                }
059                this.templateLoaderPath = templateLoaderPath;
060                if (logger.isInfoEnabled()) {
061                        logger.info("SpringTemplateLoader for FreeMarker: using resource loader [" + this.resourceLoader +
062                                        "] and template loader path [" + this.templateLoaderPath + "]");
063                }
064        }
065
066
067        @Override
068        public Object findTemplateSource(String name) throws IOException {
069                if (logger.isDebugEnabled()) {
070                        logger.debug("Looking for FreeMarker template with name [" + name + "]");
071                }
072                Resource resource = this.resourceLoader.getResource(this.templateLoaderPath + name);
073                return (resource.exists() ? resource : null);
074        }
075
076        @Override
077        public Reader getReader(Object templateSource, String encoding) throws IOException {
078                Resource resource = (Resource) templateSource;
079                try {
080                        return new InputStreamReader(resource.getInputStream(), encoding);
081                }
082                catch (IOException ex) {
083                        if (logger.isDebugEnabled()) {
084                                logger.debug("Could not find FreeMarker template: " + resource);
085                        }
086                        throw ex;
087                }
088        }
089
090        @Override
091        public long getLastModified(Object templateSource) {
092                Resource resource = (Resource) templateSource;
093                try {
094                        return resource.lastModified();
095                }
096                catch (IOException ex) {
097                        if (logger.isDebugEnabled()) {
098                                logger.debug("Could not obtain last-modified timestamp for FreeMarker template in " +
099                                                resource + ": " + ex);
100                        }
101                        return -1;
102                }
103        }
104
105        @Override
106        public void closeTemplateSource(Object templateSource) throws IOException {
107        }
108
109}