Java tutorial
/** * The MIT License (MIT) * * Copyright (c) 2015 <mickael.jeanroy@gmail.com> * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ package com.github.mjeanroy.springmvc.view.mustache.configuration; import static com.github.mjeanroy.springmvc.view.mustache.commons.PreConditions.hasText; import static com.github.mjeanroy.springmvc.view.mustache.commons.PreConditions.notNull; import com.github.mjeanroy.springmvc.view.mustache.MustacheTemplateLoader; import com.github.mjeanroy.springmvc.view.mustache.core.CompositeResourceLoader; import com.github.mjeanroy.springmvc.view.mustache.core.DefaultTemplateLoader; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.BeansException; import org.springframework.beans.factory.FactoryBean; import org.springframework.beans.factory.config.AbstractFactoryBean; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.context.ResourceLoaderAware; import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.context.support.FileSystemXmlApplicationContext; import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.Resource; import org.springframework.core.io.ResourceLoader; import org.springframework.util.ClassUtils; import java.util.Collection; import java.util.HashMap; import java.util.LinkedHashSet; import java.util.Map; /** * Factory bean for {@link com.github.mjeanroy.springmvc.view.mustache.MustacheTemplateLoader} instance. */ public class MustacheTemplateLoaderFactoryBean extends AbstractFactoryBean<MustacheTemplateLoader> implements FactoryBean<MustacheTemplateLoader>, ApplicationContextAware, ResourceLoaderAware { /** * Class logger. */ private static final Logger log = LoggerFactory.getLogger(MustacheTemplateLoaderFactoryBean.class); /** * Classpath resource loader, implemented as a singleton. */ private static final ClasspathResourceLoader CLASSPATH_RESOURCE_LOADER = new ClasspathResourceLoader(); /** * Current application context. */ private ApplicationContext applicationContext; /** * Current resource loader. */ private ResourceLoader resourceLoader; /** * @see {@link com.github.mjeanroy.springmvc.view.mustache.MustacheTemplateLoader#getPrefix()} */ private String prefix; /** * @see {@link com.github.mjeanroy.springmvc.view.mustache.MustacheTemplateLoader#getSuffix()} */ private String suffix; /** * @see {@link com.github.mjeanroy.springmvc.view.mustache.MustacheTemplateLoader#addPartialAliases(java.util.Map)} */ private final Map<String, String> partialAliases; /** * Default constructor. */ public MustacheTemplateLoaderFactoryBean() { super(); this.partialAliases = new HashMap<String, String>(); } @Override public Class<?> getObjectType() { return MustacheTemplateLoader.class; } @Override protected MustacheTemplateLoader createInstance() throws Exception { log.debug("Create instance of {}", DefaultTemplateLoader.class); DefaultTemplateLoader templateLoader = new DefaultTemplateLoader(computeResourceLoader()); templateLoader.setPrefix(prefix); templateLoader.setSuffix(suffix); templateLoader.addPartialAliases(partialAliases); return templateLoader; } @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { this.applicationContext = applicationContext; } @Override public void setResourceLoader(ResourceLoader resourceLoader) { this.resourceLoader = resourceLoader; } protected ResourceLoader computeResourceLoader() { log.debug("Build composite resource loader"); Collection<ResourceLoader> resourceLoaders = new LinkedHashSet<ResourceLoader>(); if (resourceLoader != null) { log.trace(" => Add custom resource loader: {}", resourceLoader); resourceLoaders.add(resourceLoader); } if (applicationContext != null) { log.trace(" => Add application context as resource loader: {}", applicationContext); resourceLoaders.add(applicationContext); } if (resourceLoaders.isEmpty()) { log.trace(" => Add instance of ClassPathXmlApplicationContext as resource loader"); resourceLoaders.add(new ClassPathXmlApplicationContext()); log.trace(" => Add instance of FileSystemXmlApplicationContext as resource loader"); resourceLoaders.add(new FileSystemXmlApplicationContext()); } log.debug("Add instance of classpath resource loader"); resourceLoaders.add(CLASSPATH_RESOURCE_LOADER); log.debug("Create composite resource loader using: {}", resourceLoaders); log.trace(" => Number of loaders: {}", resourceLoaders.size()); return new CompositeResourceLoader(resourceLoaders); } /** * Set {@link #prefix} * * @param prefix New {@link #prefix} */ public void setPrefix(String prefix) { this.prefix = prefix; } /** * Set {@link #suffix} * * @param suffix New {@link #suffix} */ public void setSuffix(String suffix) { this.suffix = suffix; } /** * Set {@link #partialAliases} * * @param partialAliases New {@link #partialAliases} */ public void setPartialAliases(Map<String, String> partialAliases) { this.partialAliases.putAll(partialAliases); } /** * Implementation of spring {@link org.springframework.core.io.ResourceLoader} * that will always check for resources in the classpath (not the root of the application * context). * * This class does not guarantee that resource patterns such as "file:/" or "http:" will * work, that's why this class should remain private and should not be used outside. */ private static final class ClasspathResourceLoader implements ResourceLoader { /** * Classpath prefix. */ private static final String CLASSPATH_PREFIX = "classpath:"; /** * Create new resource loader. */ private ClasspathResourceLoader() { } @Override public Resource getResource(String location) { notNull(location, "Resource location must not be null"); hasText(location, "Resource location must be defined"); // Remove the classpath if specified. // This should never happen since a previous resource loader will probably be used // before. String classpathLocation = location; if (location.startsWith(CLASSPATH_PREFIX)) { classpathLocation = location.substring(CLASSPATH_PREFIX.length()); } return new ClassPathResource(classpathLocation); } @Override public ClassLoader getClassLoader() { return ClassUtils.getDefaultClassLoader(); } } }