1
2
3
4
5
6
7
8
9
10
11
12
13 package org.abstracthorizon.danube.freemarker;
14
15 import org.abstracthorizon.danube.connection.Connection;
16 import org.abstracthorizon.danube.connection.ConnectionException;
17 import org.abstracthorizon.danube.mvc.ModelAndView;
18 import org.abstracthorizon.danube.mvc.View;
19 import org.abstracthorizon.danube.support.RuntimeIOException;
20 import org.abstracthorizon.danube.support.URLUtils;
21
22 import java.io.File;
23 import java.io.FileReader;
24 import java.io.IOException;
25 import java.io.InputStream;
26 import java.io.InputStreamReader;
27 import java.io.Reader;
28 import java.io.Writer;
29 import java.net.URL;
30 import java.net.URLConnection;
31
32 import org.slf4j.Logger;
33 import org.slf4j.LoggerFactory;
34
35 import freemarker.cache.TemplateLoader;
36 import freemarker.template.Configuration;
37 import freemarker.template.DefaultObjectWrapper;
38 import freemarker.template.Template;
39 import freemarker.template.TemplateException;
40 import freemarker.template.TemplateExceptionHandler;
41
42
43
44
45
46
47
48
49
50 public class FreeMarkerViewAdapter implements View {
51
52
53 protected Logger logger = LoggerFactory.getLogger(getClass());
54
55
56 public static final String DEFAULT_SUFFIX = ".page";
57
58
59 protected File templatesPath;
60
61
62 protected URL templatesURL;
63
64
65 protected String suffix = DEFAULT_SUFFIX;
66
67
68 protected Configuration configuration;
69
70
71
72
73 public FreeMarkerViewAdapter() {
74 }
75
76
77
78
79
80 public void init() throws RuntimeIOException {
81
82 configuration = new Configuration();
83 configuration.setTemplateLoader(createTemplateLoader());
84 DefaultObjectWrapper defaultObjectWrapper = new DefaultObjectWrapper();
85 configuration.setObjectWrapper(defaultObjectWrapper);
86 configuration.setTemplateExceptionHandler(TemplateExceptionHandler.IGNORE_HANDLER);
87 }
88
89 protected TemplateLoader createTemplateLoader() throws RuntimeIOException {
90 return new LocalTemplateLoader();
91 }
92
93
94
95
96
97
98
99 public void render(Connection connection, ModelAndView modelAndView) throws ConnectionException {
100
101 try {
102 Template template = configuration.getTemplate(makeTemplateName(modelAndView.getView()));
103 Writer writer = (Writer)connection.adapt(Writer.class);
104
105 template.process(modelAndView.getModel(), writer);
106 } catch (TemplateException templateException) {
107 throw new ConnectionException(templateException);
108 } catch (IOException e) {
109 throw new RuntimeIOException(e);
110 }
111
112
113 }
114
115
116
117
118
119 public File getTemplatesPath() {
120 return templatesPath;
121 }
122
123
124
125
126
127 public void setTemplatesPath(File templatesPath) {
128 this.templatesPath = templatesPath;
129 if (configuration != null) {
130 configuration.setTemplateLoader(createTemplateLoader());
131 }
132 }
133
134
135
136
137
138 public URL getTemplatesURL() {
139 return templatesURL;
140 }
141
142
143
144
145
146 public void setTemplatesURL(URL templatesURL) {
147 this.templatesURL = templatesURL;
148 if (templatesURL.getProtocol().equals("file")) {
149 templatesPath = new File(templatesURL.getFile());
150 }
151 }
152
153
154
155
156
157
158 protected String makeTemplateName(String view) {
159 if (suffix == null) {
160 return view;
161 } else {
162 return view + suffix;
163 }
164 }
165
166
167
168
169
170 public String getSuffix() {
171 return suffix;
172 }
173
174
175
176
177
178 public void setSuffix(String suffix) {
179 if (suffix.startsWith(".")) {
180 this.suffix = suffix;
181 } else {
182 this.suffix = "." + suffix;
183 }
184 }
185
186
187
188
189
190 public class LocalTemplateLoader implements TemplateLoader {
191
192
193 public LocalTemplateLoader() {
194 }
195
196
197
198
199
200
201 public void closeTemplateSource(Object tmp) throws IOException {
202 }
203
204
205
206
207
208
209
210
211 public Object findTemplateSource(String path) throws IOException {
212 if (templatesPath != null) {
213 File file = new File(templatesPath, path);
214 if (file.exists()) {
215 return file;
216 }
217 }
218 if (templatesURL != null) {
219 URL newURL = URLUtils.addPath(templatesURL, path);
220 try {
221 InputStream peek = newURL.openStream();
222 peek.read();
223 peek.close();
224 return newURL;
225 } catch (IOException ignore) {
226 }
227 }
228
229 return null;
230 }
231
232
233
234
235
236
237
238
239 public long getLastModified(Object tmp) {
240 if (tmp instanceof File) {
241 return ((File)tmp).lastModified();
242 } else if (tmp instanceof URL) {
243 try {
244 URLConnection connection = ((URL)tmp).openConnection();
245 return connection.getLastModified();
246 } catch (IOException ignore) {
247 }
248 }
249
250 return -1;
251 }
252
253
254
255
256
257
258
259 public Reader getReader(Object tmp, String encoding) throws IOException {
260 if (tmp instanceof File) {
261 File file = (File)tmp;
262 return new FileReader(file);
263 } else if (tmp instanceof URL) {
264 URL url = (URL)tmp;
265 return new InputStreamReader(url.openStream());
266 } else {
267 return null;
268 }
269 }
270
271 }
272 }