View Javadoc
1   /**
2    * Copyright By Grandsoft Company Limited.  
3    * 2014年5月19日 下午8:25:56
4    */
5   package gboat2.base.plugin.struts.freemarker;
6   
7   import java.io.File;
8   import java.io.IOException;
9   
10  import javax.servlet.ServletContext;
11  
12  import org.apache.struts2.ServletActionContext;
13  import org.apache.struts2.views.freemarker.FreemarkerManager;
14  import org.osgi.framework.Bundle;
15  import org.osgi.framework.FrameworkUtil;
16  
17  import com.opensymphony.xwork2.inject.Inject;
18  import com.opensymphony.xwork2.util.logging.Logger;
19  import com.opensymphony.xwork2.util.logging.LoggerFactory;
20  
21  import freemarker.cache.ClassTemplateLoader;
22  import freemarker.cache.FileTemplateLoader;
23  import freemarker.cache.MultiTemplateLoader;
24  import freemarker.cache.TemplateLoader;
25  import freemarker.cache.WebappTemplateLoader;
26  import gboat2.base.bridge.debug.DefaultDebugHook;
27  
28  /**
29   * Gboat2 平台自定义的 Freemarker 模板管理器。
30   * 在 struts-plugin.xml 中新增了如下配置,使得该模板管理器生效:
31   * <pre>
32   * 在 struts-plugin.xml 中添加了如下配置:
33   * <code>
34   * &lt;!-- 使用自定义 FreeMarker 模板管理器 --&gt;
35   * &lt;constant name="struts.freemarker.manager.classname" value="gboat2.base.plugin.struts.freemarker.GboatFreemarkerManager" /&gt;
36   * </code>
37   * </pre>
38   * @date 2014年5月19日
39   * @author <a href="mailto:[email protected]">何明旺</a>
40   * @since 3.0.0-SNAPSHOT
41   */
42  public class GboatFreemarkerManager extends FreemarkerManager {
43  
44      private static final Logger LOG = LoggerFactory.getLogger(GboatFreemarkerManager.class);
45      
46      private GboatThemeTemplateLoader themeTemplateLoader;
47      
48      @Inject
49      public void setThemeTemplateLoader(GboatThemeTemplateLoader themeTemplateLoader) {
50          this.themeTemplateLoader = themeTemplateLoader;
51      }
52  
53      @Override
54      protected void configureTemplateLoader(TemplateLoader templateLoader) {
55          themeTemplateLoader.init(templateLoader);
56          config.setTemplateLoader(themeTemplateLoader);
57      }
58  
59      @Override
60      protected TemplateLoader createTemplateLoader(ServletContext servletContext, String templatePath) {
61          TemplateLoader templatePathLoader = null;
62  
63          try {
64              if(templatePath!=null){
65                  if (templatePath.startsWith("class://")) {
66                      // substring(7) is intentional as we "reuse" the last slash
67                      templatePathLoader = new ClassTemplateLoader(getClass(), templatePath.substring(7));
68                  } else if (templatePath.startsWith("file://")) {
69                      templatePathLoader = new FileTemplateLoader(new File(templatePath.substring(7)));
70                  } else {
71                      Object action = ServletActionContext.getContext().getActionInvocation().getAction();
72                      if(action != null) {
73                          Bundle bundle = FrameworkUtil.getBundle(action.getClass());
74                          DefaultDebugHook debugHook = DefaultDebugHook.getInstance();
75                          if(bundle != null && debugHook.isBundleDebugEnabled(bundle.getSymbolicName())) {
76                              // 调试环境直接从源代码中获取 FTL 模板文件
77                              templatePathLoader = new FileTemplateLoader(new File(debugHook.getSourceFilePath(bundle.getSymbolicName(), templatePath)));
78                          }
79                      }
80                  }
81              }
82          } catch (IOException e) {
83              if (LOG.isErrorEnabled()) {
84                 LOG.error("Invalid template path specified: #0", e, e.getMessage());
85              }
86          }
87  
88          // presume that most apps will require the class and webapp template loader
89          // if people wish to
90          return templatePathLoader != null ?
91                  new MultiTemplateLoader(new TemplateLoader[]{
92                          templatePathLoader,
93                          new WebappTemplateLoader(servletContext),
94                          new GboatClassTemplateLoader()
95                  })
96                  : new MultiTemplateLoader(new TemplateLoader[]{
97                  new WebappTemplateLoader(servletContext),
98                  new GboatClassTemplateLoader()
99          });
100     }
101     
102 }