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