/* ================================================================== * Created [2009-4-27 下午11:32:55] by Jon.King * ================================================================== * TSS * ================================================================== * mailTo:jinpujun@hotmail.com * Copyright (c) Jon.King, 2009-2012 * ================================================================== */ package com.jinhe.tss.portal.engine; import java.io.File; import java.io.IOException; import java.io.OutputStreamWriter; import java.io.StringReader; import java.io.StringWriter; import java.io.Writer; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; import org.apache.log4j.Logger; import org.xml.sax.InputSource; import com.jinhe.tss.core.exception.BusinessException; import com.jinhe.tss.core.util.FileHelper; import com.jinhe.tss.core.util.URLUtil; import freemarker.ext.beans.BeansWrapper; import freemarker.ext.dom.NodeModel; import freemarker.template.Configuration; import freemarker.template.Template; import freemarker.template.TemplateException; /** * <p> FreemarkerParser.java </p> * freeMarker解析器 */ public class FreemarkerParser { protected Logger log = Logger.getLogger(this.getClass()); /** * 配置用于加载Freemarker的模板文件。 */ private Configuration cfg = new Configuration(); /** * DataModel,存放参数、静态类(statics)等 */ private Map<String, Object> root = new HashMap<String, Object>(); /** * 如果找不到freemarker模板文件,则不启用解析功能 */ public boolean isFtlTemplateReady = false; public FreemarkerParser(){ root.put("statics", BeansWrapper.getDefaultInstance().getStaticModels()); } public Map<String, Object> getDataModel() { return root; } /** * 初始化Freemarker的Configuration对象,将指定目录下的模板文件加载进来。 * 如果指定的目录为空,则默认取classes/freemarker目录的下模板文件。 * * @param templatePath */ public FreemarkerParser(File templatePath){ this(); //默认freemarker模板文件存放在WEB-INF目录下的freemarker目录里 String classpath = URLUtil.getClassesPath().getPath(); File defaultTemplatePath = new File(classpath + "/../freemarker/"); templatePath = templatePath != null ? templatePath : defaultTemplatePath; try { cfg.setDefaultEncoding("GBK"); cfg.setDirectoryForTemplateLoading(templatePath); } catch (IOException e) { log.error(" 读取 freemarker模板文件 " + templatePath + " 时IO异常,装载不成功(" + templatePath.exists() + ")", e); isFtlTemplateReady = false; return; } cfg.clearTemplateCache(); List<String> files = FileHelper.listFilesByType(".ftl", templatePath); for( String fileName : files ){ cfg.addAutoImport(fileName.substring(0, fileName.length() - 4), fileName); // 截去后缀'.ftl', 以文件自身名字命名 isFtlTemplateReady = true; } } /** * 解析模板,返回解析结果 * @param template * @return * @throws IOException * @throws TemplateException */ public String parseTemplate(String template) throws IOException, TemplateException{ Template t = new Template("temp.ftl", new StringReader(template), cfg); t.setEncoding("GBK"); Writer out2 = new StringWriter(); t.process(root, out2); return out2.toString(); } /** * 解析模板,将解析结果直接输出到Writer对象(一般为直接像前台打出结果) * @param template * @param out * @throws IOException * @throws TemplateException */ public void parseTemplate(String template, Writer out) throws IOException, TemplateException { // 便于使用单元测试时打印出结果 if(out.getClass().getName().equals("org.springframework.mock.web.MockHttpServletResponse$ResponsePrintWriter")) { out = new OutputStreamWriter(System.out); } Template t = new Template("temp.ftl", new StringReader(template), cfg); t.setEncoding("GBK"); t.process(root, out); out.flush(); } /** * 执行freemarker解析操作。<br/> * 注:需要分两次用freemarker引擎执行解析。 * * @param template * @param out * @throws IOException * @throws TemplateException */ public void parseTemplateTwice(String template, Writer out) throws IOException, TemplateException{ // 第一步,对portlet中的freemarker标签进行解析 template = parseTemplate(template); //第二步,对portlet取回的内容再进行解析(类似通过portlet取回的菜单内容中包含${PT_ip}自定义参数等) parseTemplate(template, out); } /** * 将包括request请求中的参数 和 用户自定义的参数 在内的参数加入到数据模型(DataModel)中。 * * 由于request参数多是数组的形势,所以同时要先将数组解开。 * 注:request中取出来的参数Map值为数组,一般该数组只有一个项。 * * @param params */ public void putParameters(Map<String, ? extends Object> params){ if(params == null) return; for( Entry<String, ? extends Object> entry : params.entrySet() ){ String key = entry.getKey(); Object value = params.get(key); if(value instanceof Object[]){ Object[] objs = (Object[]) value; if(objs != null && objs.length > 0) { root.put(key, objs[0]); } } else { root.put(key, value); } } } /** * 将XML数据转换为NodeModel * @param xmlValue * @return */ public static NodeModel translateValue(String xmlValue){ try { return freemarker.ext.dom.NodeModel.parse(new InputSource(new StringReader(xmlValue))); } catch (Exception e) { throw new BusinessException("Freemarker解析过程中将XML数据转换为NodeModel时出错", e); } } }