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.tiles.request.freemarker.servlet;
23
24 import java.util.Enumeration;
25 import java.util.LinkedHashMap;
26 import java.util.Map;
27
28 import javax.servlet.ServletConfig;
29 import javax.servlet.ServletContext;
30 import javax.servlet.ServletException;
31
32 import org.apache.tiles.request.reflect.ClassUtil;
33
34 import freemarker.cache.TemplateLoader;
35 import freemarker.ext.servlet.FreemarkerServlet;
36 import freemarker.template.Configuration;
37
38
39
40
41
42
43 public class SharedVariableLoaderFreemarkerServlet extends FreemarkerServlet {
44
45
46
47
48 private static final long serialVersionUID = 4301098067909854507L;
49
50
51
52
53
54
55 public static final String CUSTOM_SHARED_VARIABLE_FACTORIES_INIT_PARAM =
56 "org.apache.tiles.request.freemarker.CUSTOM_SHARED_VARIABLE_FACTORIES";
57
58
59
60
61 private Map<String, SharedVariableFactory> name2variableFactory =
62 new LinkedHashMap<String, SharedVariableFactory>();
63
64 @Override
65 public void init(ServletConfig config) throws ServletException {
66 String param = config.getInitParameter(CUSTOM_SHARED_VARIABLE_FACTORIES_INIT_PARAM);
67 if (param != null) {
68 String[] couples = param.split("\\s*;\\s*");
69 for (int i = 0; i < couples.length; i++) {
70 String[] couple = couples[i].split("\\s*,\\s*");
71 if (couple == null || couple.length != 2) {
72 throw new ServletException(
73 "Cannot parse custom shared variable partial init param: '"
74 + couples[i] + "'");
75 }
76 name2variableFactory.put(couple[0],
77 (SharedVariableFactory) ClassUtil.instantiate(couple[1]));
78 }
79 }
80 super.init(new ExcludingParameterServletConfig(config));
81 }
82
83
84
85
86
87
88
89 public void addSharedVariableFactory(String variableName, SharedVariableFactory factory) {
90 name2variableFactory.put(variableName, factory);
91 }
92
93
94 @Override
95 protected Configuration createConfiguration() {
96 Configuration configuration = super.createConfiguration();
97
98 for (Map.Entry<String, SharedVariableFactory> entry : name2variableFactory.entrySet()) {
99 configuration.setSharedVariable(entry.getKey(), entry.getValue().create());
100 }
101 return configuration;
102 }
103
104
105
106 @Override
107 protected TemplateLoader createTemplateLoader(String templatePath) {
108 return new WebappClassTemplateLoader(getServletContext());
109 }
110
111
112
113
114
115
116 private class ExcludingParameterServletConfig implements ServletConfig {
117
118
119
120
121 private ServletConfig config;
122
123
124
125
126
127
128 public ExcludingParameterServletConfig(ServletConfig config) {
129 this.config = config;
130 }
131
132 @Override
133 public String getServletName() {
134 return config.getServletName();
135 }
136
137 @Override
138 public ServletContext getServletContext() {
139 return config.getServletContext();
140 }
141
142 @Override
143 public String getInitParameter(String name) {
144 if (CUSTOM_SHARED_VARIABLE_FACTORIES_INIT_PARAM.equals(name)) {
145 return null;
146 }
147 return config.getInitParameter(name);
148 }
149
150 @SuppressWarnings({ "rawtypes", "unchecked" })
151 @Override
152 public Enumeration getInitParameterNames() {
153 return new SkippingEnumeration(config.getInitParameterNames());
154 }
155
156 }
157
158
159
160
161
162
163 private static class SkippingEnumeration implements Enumeration<String> {
164
165
166
167
168 private Enumeration<String> enumeration;
169
170
171
172
173 private String next = null;
174
175
176
177
178
179
180 public SkippingEnumeration(Enumeration<String> enumeration) {
181 this.enumeration = enumeration;
182 updateNextElement();
183 }
184
185 @Override
186 public boolean hasMoreElements() {
187 return next != null;
188 }
189
190 @Override
191 public String nextElement() {
192 String retValue = next;
193 updateNextElement();
194 return retValue;
195 }
196
197
198
199
200 private void updateNextElement() {
201 String value = null;
202 boolean done = false;
203 while (this.enumeration.hasMoreElements() && !done) {
204 value = this.enumeration.nextElement();
205 if (value.equals(CUSTOM_SHARED_VARIABLE_FACTORIES_INIT_PARAM)) {
206 value = null;
207 } else {
208 done = true;
209 }
210 }
211 next = value;
212 }
213
214 }
215 }