1
2
3
4
5 package gboat2.base.plugin.struts.freemarker;
6
7 import java.io.File;
8 import java.io.IOException;
9 import java.util.List;
10
11 import org.apache.commons.lang3.ObjectUtils;
12 import org.apache.struts2.StrutsConstants;
13 import org.apache.struts2.components.template.Template;
14 import org.apache.struts2.components.template.TemplateEngine;
15 import org.apache.struts2.views.freemarker.FreemarkerThemeTemplateLoader;
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.FileTemplateLoader;
22 import freemarker.cache.MultiTemplateLoader;
23 import freemarker.cache.TemplateLoader;
24 import gboat2.base.bridge.debug.DefaultDebugHook;
25 import gboat2.base.bridge.exception.DefaultGboatNestedException;
26
27
28
29
30
31
32
33
34
35
36
37 public class GboatThemeTemplateLoader extends FreemarkerThemeTemplateLoader {
38
39 protected String gboatViewResourcePath;
40 protected MultiTemplateLoader sourceTemplateLoader;
41
42
43 protected String themeExpansionToken;
44 protected TemplateEngine templateEngine;
45
46
47 private static final Logger LOG = LoggerFactory.getLogger(GboatThemeTemplateLoader.class);
48
49 public GboatThemeTemplateLoader() {
50 super();
51
52 String view = "gboat2.base.view";
53 DefaultDebugHook debugHook = DefaultDebugHook.getInstance();
54 if(debugHook.isBundleDebugEnabled(view)) {
55 gboatViewResourcePath = debugHook.getResourcesAbsolutPath(view);
56 try {
57 sourceTemplateLoader = new MultiTemplateLoader(new TemplateLoader[] {
58 new FileTemplateLoader(new File(gboatViewResourcePath), true)
59 });
60 } catch (IOException e) {
61 throw new DefaultGboatNestedException(e);
62 }
63 }
64 }
65
66 @Override
67 public Object findTemplateSource(String name) throws IOException {
68 int tokenIndex = (name == null) ? -1 : name.indexOf(themeExpansionToken);
69 if (tokenIndex < 0) {
70 return ObjectUtils.defaultIfNull(findTemplateSourceFromSourceFile(name), getParentTemplateLoader().findTemplateSource(name));
71 }
72
73 int themeEndIndex = name.indexOf('/', tokenIndex);
74 if (themeEndIndex < 0) {
75 return ObjectUtils.defaultIfNull(findTemplateSourceFromSourceFile(name), getParentTemplateLoader().findTemplateSource(name));
76 }
77
78 Template template = new Template(
79 name.substring(0, tokenIndex - 1),
80 name.substring(tokenIndex + themeExpansionToken.length(), themeEndIndex),
81 name.substring(themeEndIndex + 1));
82
83 List<Template> possibleTemplates = template.getPossibleTemplates(templateEngine);
84 for (Template possibleTemplate : possibleTemplates) {
85 Object templateSource = findTemplateSourceFromSourceFile(possibleTemplate.toString());
86 if (templateSource != null)
87 return templateSource;
88
89 templateSource = getParentTemplateLoader().findTemplateSource(
90 possibleTemplate.toString().substring(1));
91 if (templateSource != null) {
92 return templateSource;
93 }
94 }
95 String parentTheme = (String) templateEngine.getThemeProps(template).get("parent");
96 if (parentTheme == null) {
97
98 return null;
99 }
100 String parentName = "/" + template.getDir() + "/" + themeExpansionToken + parentTheme + "/" + template.getName();
101 return ObjectUtils.defaultIfNull(findTemplateSourceFromSourceFile(name), this.findTemplateSource(parentName));
102 }
103
104 private Object findTemplateSourceFromSourceFile (String name) {
105
106 if(gboatViewResourcePath == null)
107 return null;
108
109 File sourceFile = new File(gboatViewResourcePath, name);
110 if(sourceFile.isFile()){
111 try {
112 return sourceTemplateLoader.findTemplateSource(name);
113 } catch (IOException e) {
114 LOG.warn("读取标签模板的源文件 [#0] 失败。", e, sourceFile.getAbsolutePath());
115 }
116 }
117 return null;
118 }
119
120 @Inject(StrutsConstants.STRUTS_UI_THEME_EXPANSION_TOKEN)
121 public void setUIThemeExpansionToken(String token) {
122 themeExpansionToken = token;
123 }
124
125 @Inject("ftl")
126 public void setTemplateEngine(TemplateEngine templateEngine) {
127 this.templateEngine = templateEngine;
128 }
129
130 }