1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 package org.apache.struts2.components.template;
23
24 import java.util.Collections;
25 import java.util.HashMap;
26 import java.util.Map;
27 import java.util.Set;
28
29 import com.opensymphony.xwork2.config.ConfigurationException;
30 import com.opensymphony.xwork2.inject.Container;
31 import com.opensymphony.xwork2.inject.Inject;
32
33 /***
34 * The TemplateEngineManager will return a template engine for the template
35 */
36 public class TemplateEngineManager {
37 public static final String DEFAULT_TEMPLATE_TYPE_CONFIG_KEY = "struts.ui.templateSuffix";
38
39 /*** The default template extenstion is <code>ftl</code>. */
40 public static final String DEFAULT_TEMPLATE_TYPE = "ftl";
41
42
43 Map<String,EngineFactory> templateEngines = new HashMap<String,EngineFactory>();
44 Container container;
45 String defaultTemplateType;
46
47 @Inject(DEFAULT_TEMPLATE_TYPE_CONFIG_KEY)
48 public void setDefaultTemplateType(String type) {
49 this.defaultTemplateType = type;
50 }
51
52 @Inject
53 public void setContainer(Container container) {
54 this.container = container;
55 Map<String,EngineFactory> map = new HashMap<String,EngineFactory>();
56 Set<String> prefixes = container.getInstanceNames(TemplateEngine.class);
57 for (String prefix : prefixes) {
58 map.put(prefix, new LazyEngineFactory(prefix));
59 }
60 this.templateEngines = Collections.unmodifiableMap(map);
61
62 }
63
64 /***
65 * Registers the given template engine.
66 * <p/>
67 * Will add the engine to the existing list of known engines.
68 * @param templateExtension filename extension (eg. .jsp, .ftl, .vm).
69 * @param templateEngine the engine.
70 */
71 public void registerTemplateEngine(String templateExtension, final TemplateEngine templateEngine) {
72 templateEngines.put(templateExtension, new EngineFactory() {
73 public TemplateEngine create() {
74 return templateEngine;
75 }
76 });
77 }
78
79 /***
80 * Gets the TemplateEngine for the template name. If the template name has an extension (for instance foo.jsp), then
81 * this extension will be used to look up the appropriate TemplateEngine. If it does not have an extension, it will
82 * look for a Configuration setting "struts.ui.templateSuffix" for the extension, and if that is not set, it
83 * will fall back to "ftl" as the default.
84 *
85 * @param template Template used to determine which TemplateEngine to return
86 * @param templateTypeOverride Overrides the default template type
87 * @return the engine.
88 */
89 public TemplateEngine getTemplateEngine(Template template, String templateTypeOverride) {
90 String templateType = DEFAULT_TEMPLATE_TYPE;
91 String templateName = template.toString();
92 if (templateName.indexOf(".") > 0) {
93 templateType = templateName.substring(templateName.indexOf(".") + 1);
94 } else if (templateTypeOverride !=null && templateTypeOverride.length() > 0) {
95 templateType = templateTypeOverride;
96 } else {
97 String type = defaultTemplateType;
98 if (type != null) {
99 templateType = type;
100 }
101 }
102 return templateEngines.get(templateType).create();
103 }
104
105 /*** Abstracts loading of the template engine */
106 interface EngineFactory {
107 public TemplateEngine create();
108 }
109
110 /***
111 * Allows the template engine to be loaded at request time, so that engines that are missing
112 * dependencies aren't accessed if never used.
113 */
114 class LazyEngineFactory implements EngineFactory {
115 private String name;
116 public LazyEngineFactory(String name) {
117 this.name = name;
118 }
119 public TemplateEngine create() {
120 TemplateEngine engine = container.getInstance(TemplateEngine.class, name);
121 if (engine == null) {
122 throw new ConfigurationException("Unable to locate template engine: "+name);
123 }
124 return engine;
125 }
126 }
127 }