package org.beanfuse.struts2.view.freemarker; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.net.URL; import java.util.Enumeration; import java.util.Iterator; import java.util.Properties; import javax.servlet.ServletContext; import org.apache.struts2.views.freemarker.StrutsClassTemplateLoader; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import freemarker.cache.FileTemplateLoader; import freemarker.cache.MultiTemplateLoader; import freemarker.cache.TemplateLoader; import freemarker.cache.WebappTemplateLoader; import freemarker.ext.beans.BeansWrapper; import freemarker.template.TemplateException; public class FreemarkerManager extends org.apache.struts2.views.freemarker.FreemarkerManager { private final Logger logger = LoggerFactory.getLogger(FreemarkerManager.class); protected BeansWrapper getObjectWrapper() { BeansWrapper wrapper = new BeanfuseWrapper(altMapWrapper); wrapper.setUseCache(cacheBeanWrapper); return wrapper; } /** * The default template loader is a MultiTemplateLoader which includes a * ClassTemplateLoader and a WebappTemplateLoader (and a FileTemplateLoader * depending on the init-parameter 'TemplatePath'). * <p/> * The ClassTemplateLoader will resolve fully qualified template includes * that begin with a slash. for example /com/company/template/common.ftl * <p/> * The WebappTemplateLoader attempts to resolve templates relative to the * web root folder */ protected TemplateLoader getTemplateLoader(ServletContext servletContext) { // construct a FileTemplateLoader for the init-param 'TemplatePath' FileTemplateLoader templatePathLoader = null; String templatePath = servletContext.getInitParameter("TemplatePath"); if (templatePath == null) { templatePath = servletContext.getInitParameter("templatePath"); } if (templatePath != null) { try { templatePathLoader = new FileTemplateLoader(new File(templatePath)); } catch (IOException e) { logger.error("Invalid template path specified:{} ", e.getMessage(), e); } } String webappTemplatePath = servletContext.getInitParameter("webappTemplatePath"); WebappTemplateLoader wtl = null; if (null != webappTemplatePath) { wtl = new WebappTemplateLoader(servletContext, webappTemplatePath); } else { wtl = new WebappTemplateLoader(servletContext); } StrutsClassTemplateLoader strutsClassTemplateLoader = new StrutsClassTemplateLoader(); // 带有固定前缀的类模板加载器 PrefixClassTemplateLoader prefixClassTemplateLoader = new PrefixClassTemplateLoader( webappTemplatePath); // presume that most apps will require the class and webapp template // loader // if people wish to return templatePathLoader != null ? new MultiTemplateLoader(new TemplateLoader[] { templatePathLoader, wtl, strutsClassTemplateLoader, prefixClassTemplateLoader }) : new MultiTemplateLoader(new TemplateLoader[] { wtl, strutsClassTemplateLoader, prefixClassTemplateLoader }); } /** * Load the settings from the /META-INF/freemarker.properties and * /freemarker.properties file on the classpath * * @see freemarker.template.Configuration#setSettings for the definition of * valid settings */ protected void loadSettings(ServletContext servletContext, freemarker.template.Configuration configuration) { try { Properties properties = new Properties(); Enumeration em = FreemarkerManager.class.getClassLoader().getResources( "META-INF/freemarker.properties"); while (em.hasMoreElements()) { properties.putAll(getProperties((URL) em.nextElement())); } em = FreemarkerManager.class.getClassLoader().getResources("freemarker.properties"); while (em.hasMoreElements()) { properties.putAll(getProperties((URL) em.nextElement())); } configuration.setSettings(properties); for (Iterator iter = properties.keySet().iterator(); iter.hasNext();) { String key = (String) iter.next(); logger.info("{}={}", key, properties.get(key)); } } catch (IOException e) { logger.error("Error while loading freemarker.properties", e); } catch (TemplateException e) { logger.error("Error while setting freemarker.properties", e); } } private Properties getProperties(URL url) { logger.info("loading {}", url); InputStream in = null; try { in = url.openStream(); if (in != null) { Properties p = new Properties(); p.load(in); return p; } } catch (IOException e) { logger.error("Error while loading " + url, e); } finally { if (in != null) { try { in.close(); } catch (IOException io) { logger.warn("Unable to close input stream", io); } } } return null; } }