1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45 package org.melati.template;
46
47 import java.io.IOException;
48 import java.text.DateFormat;
49
50 import org.melati.Melati;
51 import org.melati.poem.Field;
52 import org.melati.poem.PoemLocale;
53 import org.melati.util.MelatiStringWriter;
54 import org.melati.util.MelatiWriter;
55
56 /**
57 * MarkupLanguage provides a variety of methods for rendering objects in a
58 * template.
59 *
60 * Each object to be rendered has 3 methods:
61 * 1 - String rendered(Object o) - this will render the object to a String
62 * 2 - void render(Object o) - renders the object to melati.getWriter()
63 * 3 - void render(Object o, MelatiWriter w) - render the object to w.
64 *
65 * When this class was written it was thought that for maximum
66 * efficiency one should render the object direct to the output stream using
67 * method (2) above.
68 * However now all but (1) is deprecated.
69 */
70
71 public abstract class AbstractMarkupLanguage implements MarkupLanguage {
72
73 protected TempletLoader templetLoader = null;
74 protected Melati melati = null;
75 protected PoemLocale locale = null;
76
77 /** The maximum number of field possibilites to render. */
78 public static final int FIELD_POSSIBILITIES_LIMIT = 10000;
79
80 private String name;
81
82 /**
83 * Construct a Markup Language object.
84 *
85 * @param name - the name associated with this markup language.
86 * This is used to determine where to load
87 * templates from ie 'html' templates are
88 * found in the 'html' directory.
89 * @param melati - the melati currently in use
90 * @param templetLoader - the template loader in use
91 * (taken from org.melati.MelatiConfig.properties)
92 * @param locale - the locale in use
93 * (taken from org.melati.MelatiConfig.properties)
94 */
95 public AbstractMarkupLanguage(String name,
96 Melati melati,
97 TempletLoader templetLoader,
98 PoemLocale locale) {
99 this.name = name;
100 this.melati = melati;
101 this.templetLoader = templetLoader;
102 this.locale = locale;
103 }
104
105 /**
106 * Construct a new MarkupLanguage given a new name and an
107 * existing MarkupLanguage.
108 *
109 * @param name - the name of the new MarkupLanguage
110 * @param other - the Markup Language to base this one upon
111 */
112 protected AbstractMarkupLanguage(String name, AbstractMarkupLanguage other) {
113 this(name, other.melati, other.templetLoader, other.locale);
114 }
115
116 /**
117 * {@inheritDoc}
118 * @see org.melati.template.MarkupLanguage#getName()
119 */
120 public String getName() {
121 return name;
122 }
123
124 /**
125 * Name and locale.
126 * {@inheritDoc}
127 * @see java.lang.Object#toString()
128 */
129 public String toString() {
130 return getName() + "/" + locale.toString();
131 }
132
133 private MelatiStringWriter getStringWriter() {
134 return (MelatiStringWriter)melati.getStringWriter();
135 }
136
137 /**
138 * {@inheritDoc}
139 * @see org.melati.template.MarkupLanguage#rendered(java.lang.String, int)
140 */
141 public String rendered(String s, int limit) throws IOException {
142 MelatiStringWriter sw = getStringWriter();
143 render(s,limit,sw);
144 return sw.toString();
145 }
146
147 /**
148 * {@inheritDoc}
149 * @see org.melati.template.MarkupLanguage#rendered(org.melati.poem.Field, int, int)
150 */
151 public String rendered(Field field, int style, int limit)
152 throws TemplateEngineException, IOException {
153 MelatiStringWriter sw = getStringWriter();
154 render(field, style, limit, sw);
155 return sw.toString();
156 }
157
158 /**
159 * {@inheritDoc}
160 * @see org.melati.template.MarkupLanguage#rendered(org.melati.poem.Field, int)
161 */
162 public String rendered(Field field, int style)
163 throws TemplateEngineException, IOException {
164 MelatiStringWriter sw = getStringWriter();
165 render(field, style, FIELD_POSSIBILITIES_LIMIT, sw);
166 return sw.toString();
167 }
168
169 /**
170 * {@inheritDoc}
171 * @see org.melati.template.MarkupLanguage#rendered(java.lang.Object)
172 */
173 public String rendered(Object o)
174 throws IOException {
175 MelatiStringWriter sw = getStringWriter();
176 if (o instanceof String)
177 render((String)o, sw);
178 else if (o instanceof Field)
179 render((Field)o, sw);
180 else
181 render(o, sw);
182 return sw.toString();
183 }
184
185
186 /**
187 * Render a String in a MarkupLanguage specific way, limiting it's length.
188 * Render to a supplied MelatiWriter.
189 *
190 * @param s - the string to be rendered
191 * @param writer - the MelatiWriter to render this String to
192 * @param limit - the lenght to trim the string to
193 * @throws IOException - if there is a problem during rendering
194 */
195 protected void render(String s, int limit, MelatiWriter writer)
196 throws IOException {
197 render(s.length() < limit + 3 ? s : s.substring(0, limit) + "...", writer);
198 }
199
200 /**
201 * Render a String in a MarkupLanguage specific way
202 * to a supplied MelatiWriter.
203 *
204 * @param s - the string to be rendered
205 * @param writer - the MelatiWriter to render this String to
206 * @throws IOException - if there is a problem during rendering
207 */
208 protected abstract void render(String s, MelatiWriter writer) throws IOException;
209
210 /**
211 * Render a Field Object in a MarkupLanguage specific way,
212 * rendering to supplied MelatiWriter.
213 *
214 * @param field - the Field to be rendered
215 * @param writer - the MelatiWriter to render this Object to
216 * @throws IOException - if there is a problem during rendering
217 */
218 protected void render(Field field, MelatiWriter writer) throws IOException {
219 render(field, DateFormat.MEDIUM, FIELD_POSSIBILITIES_LIMIT, writer);
220 }
221
222 /**
223 * Render a Field Object in a MarkupLanguage specific way,
224 * rendering to supplied MelatiWriter.
225 *
226 * @param field - the Field to be rendered
227 * @param style - a style to format this Field.
228 * @see org.melati.poem.DatePoemType#stringOfCooked
229 * (java.lang.Object,org.melati.poem.PoemLocale, int)
230 * @param limit - the length to trim the rendered string to
231 * @param writer - the MelatiWriter to render this Object to
232 * @throws IOException - if there is a problem during rendering
233 */
234 protected void render(Field field, int style, int limit, MelatiWriter writer)
235 throws IOException {
236 render(field.getCookedString(locale, style), limit, writer);
237 }
238
239
240 /**
241 * {@inheritDoc}
242 * @see org.melati.template.MarkupLanguage#renderedStart(org.melati.poem.Field)
243 */
244 public String renderedStart(Field field)
245 throws IOException {
246 MelatiStringWriter sw = getStringWriter();
247 renderStart(field, sw);
248 return sw.toString();
249 }
250
251
252 protected void renderStart(Field field, MelatiWriter writer)
253 throws IOException {
254 render(field, DateFormat.MEDIUM, 50, writer);
255 }
256
257 /**
258 * Render an Object in a MarkupLanguage specific way, rendering to
259 * the <code>MelatiWriter</code> supplied by <code>melati.getWriter()</code>.
260 *
261 * @param o - the Object to be rendered
262 * @throws IOException - if there is a problem during rendering
263 * @throws TemplateEngineException - if there is a problem with the
264 * ServletTemplateEngine
265 */
266 protected void render(Object o) throws IOException {
267 MelatiWriter writer = melati.getWriter();
268 render(o, writer);
269 }
270
271 /**
272 * Render an Object in a MarkupLanguage specific way, rendering to
273 * a supplied Writer.
274 *
275 * NOTE The context always contains objects with the names melati, object and ml
276 *
277 * @param o - the Object to be rendered
278 * @param writer - the MelatiWriter to render this Object to
279 */
280 protected void render(Object o, MelatiWriter writer) throws IOException {
281 if (o == null)
282 throw new NullPointerException();
283 else {
284 TemplateContext vars =
285 melati.getTemplateEngine().getTemplateContext(melati);
286 Template templet =
287 templetLoader.templet(melati.getTemplateEngine(), this, o.getClass());
288 vars.put("object", o);
289
290 if (o instanceof Field) vars.put("field", o);
291 vars.put("melati", melati);
292 vars.put("ml", melati.getMarkupLanguage());
293 expandTemplet(templet, vars, writer);
294 }
295 }
296
297
298
299
300
301
302
303
304 /**
305 * {@inheritDoc}
306 * @see org.melati.template.MarkupLanguage#input(org.melati.poem.Field)
307 */
308 public String input(Field field)
309 throws TemplateEngineException,
310 IOException, NotFoundException {
311 return input(field, null, "", false);
312 }
313
314 /**
315 * {@inheritDoc}
316 * @see org.melati.template.MarkupLanguage#inputAs(org.melati.poem.Field, java.lang.String)
317 */
318 public String inputAs(Field field, String templetName)
319 throws TemplateEngineException,
320 IOException, NotFoundException {
321 return input(field, templetName, "", false);
322 }
323
324 /**
325 * {@inheritDoc}
326 * @see org.melati.template.MarkupLanguage#searchInput(org.melati.poem.Field, java.lang.String)
327 */
328 public String searchInput(Field field, String nullValue)
329 throws TemplateEngineException,
330 IOException, NotFoundException{
331 return input(field, null, nullValue, true);
332 }
333
334 protected String input(Field field,
335 String templetName,
336 String nullValue,
337 boolean overrideNullable)
338 throws IOException, NotFoundException {
339
340 Template templet;
341 templet =
342 templetName == null ?
343 templetLoader.templet(melati.getTemplateEngine(), this, field) :
344 templetLoader.templet(melati.getTemplateEngine(), this, templetName);
345
346 TemplateContext vars =
347 melati.getTemplateEngine().getTemplateContext(melati);
348
349 if (overrideNullable) {
350 field = field.withNullable(true);
351 vars.put("nullValue", nullValue);
352 }
353
354 vars.put("melati", melati);
355 vars.put("ml", melati.getMarkupLanguage());
356 vars.put("object", field);
357 vars.put("field", field);
358 MelatiStringWriter sw = getStringWriter();
359 melati.getTemplateEngine().expandTemplate(sw, templet,vars);
360
361 return sw.toString();
362 }
363
364
365 /**
366 * Interpolate a templet and write it out.
367 *
368 * @param templet {@link Template} to interpolate
369 * @param tc {@link TemplateContext} against which to instantiate variables
370 * @param out {@link MelatiWriter} to write results to
371 * @throws TemplateEngineException if something unexpected happens
372 */
373 protected void expandTemplet(Template templet, TemplateContext tc,
374 MelatiWriter out) throws IOException {
375 melati.getTemplateEngine().expandTemplate(out, templet, tc);
376 }
377 }
378
379