001/*
002 * Copyright 2012-2016 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 *      http://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.boot.autoconfigure.mustache;
018
019import javax.annotation.PostConstruct;
020
021import com.samskivert.mustache.Mustache;
022import com.samskivert.mustache.Mustache.Collector;
023import com.samskivert.mustache.Mustache.Compiler;
024import com.samskivert.mustache.Mustache.TemplateLoader;
025import org.apache.commons.logging.Log;
026import org.apache.commons.logging.LogFactory;
027
028import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
029import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
030import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
031import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
032import org.springframework.boot.autoconfigure.mustache.web.MustacheViewResolver;
033import org.springframework.boot.autoconfigure.template.TemplateLocation;
034import org.springframework.boot.context.properties.EnableConfigurationProperties;
035import org.springframework.context.ApplicationContext;
036import org.springframework.context.annotation.Bean;
037import org.springframework.context.annotation.Configuration;
038import org.springframework.core.Ordered;
039import org.springframework.core.env.Environment;
040
041/**
042 * {@link EnableAutoConfiguration Auto-configuration} for Mustache.
043 *
044 * @author Dave Syer
045 * @since 1.2.2
046 */
047@Configuration
048@ConditionalOnClass(Mustache.class)
049@EnableConfigurationProperties(MustacheProperties.class)
050public class MustacheAutoConfiguration {
051
052        private static final Log logger = LogFactory.getLog(MustacheAutoConfiguration.class);
053
054        private final MustacheProperties mustache;
055
056        private final Environment environment;
057
058        private final ApplicationContext applicationContext;
059
060        public MustacheAutoConfiguration(MustacheProperties mustache, Environment environment,
061                        ApplicationContext applicationContext) {
062                this.mustache = mustache;
063                this.environment = environment;
064                this.applicationContext = applicationContext;
065        }
066
067        @PostConstruct
068        public void checkTemplateLocationExists() {
069                if (this.mustache.isCheckTemplateLocation()) {
070                        TemplateLocation location = new TemplateLocation(this.mustache.getPrefix());
071                        if (!location.exists(this.applicationContext)) {
072                                logger.warn("Cannot find template location: " + location
073                                                + " (please add some templates, check your Mustache "
074                                                + "configuration, or set spring.mustache."
075                                                + "check-template-location=false)");
076                        }
077                }
078        }
079
080        @Bean
081        @ConditionalOnMissingBean(Mustache.Compiler.class)
082        public Mustache.Compiler mustacheCompiler(TemplateLoader mustacheTemplateLoader) {
083                return Mustache.compiler().withLoader(mustacheTemplateLoader)
084                                .withCollector(collector());
085        }
086
087        private Collector collector() {
088                MustacheEnvironmentCollector collector = new MustacheEnvironmentCollector();
089                collector.setEnvironment(this.environment);
090                return collector;
091        }
092
093        @Bean
094        @ConditionalOnMissingBean(TemplateLoader.class)
095        public MustacheResourceTemplateLoader mustacheTemplateLoader() {
096                MustacheResourceTemplateLoader loader = new MustacheResourceTemplateLoader(
097                                this.mustache.getPrefix(), this.mustache.getSuffix());
098                loader.setCharset(this.mustache.getCharsetName());
099                return loader;
100        }
101
102        @Configuration
103        @ConditionalOnWebApplication
104        protected static class MustacheWebConfiguration {
105
106                private final MustacheProperties mustache;
107
108                protected MustacheWebConfiguration(MustacheProperties mustache) {
109                        this.mustache = mustache;
110                }
111
112                @Bean
113                @ConditionalOnMissingBean(MustacheViewResolver.class)
114                public MustacheViewResolver mustacheViewResolver(Compiler mustacheCompiler) {
115                        MustacheViewResolver resolver = new MustacheViewResolver();
116                        this.mustache.applyToViewResolver(resolver);
117                        resolver.setCharset(this.mustache.getCharsetName());
118                        resolver.setCompiler(mustacheCompiler);
119                        resolver.setOrder(Ordered.LOWEST_PRECEDENCE - 10);
120                        return resolver;
121                }
122
123        }
124
125}