1 package org.apache.velocity.app.tools;
2
3 /*
4 * Licensed to the Apache Software Foundation (ASF) under one
5 * or more contributor license agreements. See the NOTICE file
6 * distributed with this work for additional information
7 * regarding copyright ownership. The ASF licenses this file
8 * to you under the Apache License, Version 2.0 (the
9 * "License"); you may not use this file except in compliance
10 * with the License. You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing,
15 * software distributed under the License is distributed on an
16 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17 * KIND, either express or implied. See the License for the
18 * specific language governing permissions and limitations
19 * under the License.
20 */
21
22 import java.lang.reflect.Array;
23 import java.text.DateFormat;
24 import java.util.Date;
25 import java.util.List;
26
27 import org.apache.velocity.context.Context;
28
29 /**
30 * Formatting tool for inserting into the Velocity WebContext. Can
31 * format dates or lists of objects.
32 *
33 * <p>Here's an example of some uses:
34 *
35 * <code><pre>
36 * $formatter.formatShortDate($object.Date)
37 * $formatter.formatLongDate($db.getRecord(232).getDate())
38 * $formatter.formatArray($array)
39 * $formatter.limitLen(30, $object.Description)
40 * </pre></code>
41 *
42 * @deprecated This class has been replaced by NumberTool, DateTool,
43 * DisplayTool, and AlternatorTool available from the Velocity-Tools sub-project.
44 * VelocityFormatter will be removed in a future version of Velocity.
45 *
46 * @author <a href="sean@somacity.com">Sean Legassick</a>
47 * @author <a href="dlr@collab.net">Daniel Rall</a>
48 * @version $Id: VelocityFormatter.java 544641 2007-06-05 21:30:22Z nbubna $
49 */
50 public class VelocityFormatter
51 {
52 Context context = null;
53
54 /**
55 * Constructor needs a backpointer to the context.
56 *
57 * @param context A Context.
58 */
59 public VelocityFormatter(Context context)
60 {
61 this.context = context;
62 }
63
64 /**
65 * Formats a date in <code>DateFormat.SHORT</code> style.
66 *
67 * @param date The date to format.
68 * @return The formatted date as text.
69 */
70 public String formatShortDate(Date date)
71 {
72 return DateFormat.getDateInstance(DateFormat.SHORT).format(date);
73 }
74
75 /**
76 * Formats a date in <code>DateFormat.LONG</code> style.
77 *
78 * @param date The date to format.
79 * @return The formatted date as text.
80 */
81 public String formatLongDate(Date date)
82 {
83 return DateFormat.getDateInstance(DateFormat.LONG).format(date);
84 }
85
86 /**
87 * Formats a date/time in 'short' style.
88 *
89 * @param date The date to format.
90 * @return The formatted date as text.
91 */
92 public String formatShortDateTime(Date date)
93 {
94 return DateFormat
95 .getDateTimeInstance(DateFormat.SHORT,
96 DateFormat.SHORT).format(date);
97 }
98
99 /**
100 * Formats a date/time in 'long' style.
101 *
102 * @param date The date to format.
103 * @return The formatted date as text.
104 */
105 public String formatLongDateTime(Date date)
106 {
107 return DateFormat.getDateTimeInstance(
108 DateFormat.LONG, DateFormat.LONG).format(date);
109 }
110
111 /**
112 * Formats an array into the form "A, B and C".
113 *
114 * @param array An Object.
115 * @return A String.
116 */
117 public String formatArray(Object array)
118 {
119 return formatArray(array, ", ", " and ");
120 }
121
122 /**
123 * Formats an array into the form
124 * "A<delim>B<delim>C".
125 *
126 * @param array An Object.
127 * @param delim A String.
128 * @return A String.
129 */
130 public String formatArray(Object array,
131 String delim)
132 {
133 return formatArray(array, delim, delim);
134 }
135
136 /**
137 * Formats an array into the form
138 * "A<delim>B<finaldelim>C".
139 *
140 * @param array An Object.
141 * @param delim A String.
142 * @param finaldelim A String.
143 * @return A String.
144 */
145 public String formatArray(Object array,
146 String delim,
147 String finaldelim)
148 {
149 StringBuffer sb = new StringBuffer();
150 int arrayLen = Array.getLength(array);
151 for (int i = 0; i < arrayLen; i++)
152 {
153 // Use the Array.get method as this will automatically
154 // wrap primitive types in a suitable Object-derived
155 // wrapper if necessary.
156 sb.append(Array.get(array, i).toString());
157 if (i < arrayLen - 2)
158 {
159 sb.append(delim);
160 }
161 else if (i < arrayLen - 1)
162 {
163 sb.append(finaldelim);
164 }
165 }
166 return sb.toString();
167 }
168
169 /**
170 * Formats a vector into the form "A, B and C".
171 *
172 * @param list The list of elements to format.
173 * @return A String.
174 */
175 public String formatVector(List list)
176 {
177 return formatVector(list, ", ", " and ");
178 }
179
180 /**
181 * Formats a vector into the form "A<delim>B<delim>C".
182 *
183 * @param list The list of elements to format.
184 * @param delim A String.
185 * @return A String.
186 */
187 public String formatVector(List list,
188 String delim)
189 {
190 return formatVector(list, delim, delim);
191 }
192
193 /**
194 * Formats a list into the form
195 * "Adelim>B<finaldelim>C".
196 *
197 * @param list The list of elements to format.
198 * @param delim A String.
199 * @param finaldelim A String.
200 * @return A String.
201 */
202 public String formatVector(List list,
203 String delim,
204 String finaldelim)
205 {
206 StringBuffer sb = new StringBuffer();
207 int size = list.size();
208 for (int i = 0; i < size; i++)
209 {
210 sb.append(list.get(i));
211 if (i < size - 2)
212 {
213 sb.append(delim);
214 }
215 else if (i < size - 1)
216 {
217 sb.append(finaldelim);
218 }
219 }
220 return sb.toString();
221 }
222
223 /**
224 * Limits 'string' to 'maxlen' characters. If the string gets
225 * curtailed, "..." is appended to it.
226 *
227 * @param maxlen An int with the maximum length.
228 * @param string A String.
229 * @return A String.
230 */
231 public String limitLen(int maxlen,
232 String string)
233 {
234 return limitLen(maxlen, string, "...");
235 }
236
237 /**
238 * Limits 'string' to 'maxlen' character. If the string gets
239 * curtailed, 'suffix' is appended to it.
240 *
241 * @param maxlen An int with the maximum length.
242 * @param string A String.
243 * @param suffix A String.
244 * @return A String.
245 */
246 public String limitLen(int maxlen,
247 String string,
248 String suffix)
249 {
250 String ret = string;
251 if (string.length() > maxlen)
252 {
253 ret = string.substring(0, maxlen - suffix.length()) + suffix;
254 }
255 return ret;
256 }
257
258 /**
259 * Class that returns alternating values in a template. It stores
260 * a list of alternate Strings, whenever alternate() is called it
261 * switches to the next in the list. The current alternate is
262 * retrieved through toString() - i.e. just by referencing the
263 * object in a Velocity template. For an example of usage see the
264 * makeAlternator() method below.
265 */
266 public class VelocityAlternator
267 {
268 /**
269 *
270 */
271 protected String[] alternates = null;
272 /**
273 *
274 */
275 protected int current = 0;
276
277 /**
278 * Constructor takes an array of Strings.
279 *
280 * @param alternates A String[].
281 */
282 public VelocityAlternator(String[] alternates)
283 {
284 this.alternates = alternates;
285 }
286
287 /**
288 * Alternates to the next in the list.
289 *
290 * @return The current alternate in the sequence.
291 */
292 public String alternate()
293 {
294 current++;
295 current %= alternates.length;
296 return "";
297 }
298
299 /**
300 * Returns the current alternate.
301 *
302 * @return A String.
303 */
304 public String toString()
305 {
306 return alternates[current];
307 }
308 }
309
310 /**
311 * As VelocityAlternator, but calls <code>alternate()</code>
312 * automatically on rendering in a template.
313 */
314 public class VelocityAutoAlternator extends VelocityAlternator
315 {
316 /**
317 * Constructor takes an array of Strings.
318 *
319 * @param alternates A String[].
320 */
321 public VelocityAutoAlternator(String[] alternates)
322 {
323 super(alternates);
324 }
325
326 /**
327 * Returns the current alternate, and automatically alternates
328 * to the next alternate in its sequence (trigged upon
329 * rendering).
330 *
331 * @return The current alternate in the sequence.
332 */
333 public final String toString()
334 {
335 String s = alternates[current];
336 alternate();
337 return s;
338 }
339 }
340
341 /**
342 * Makes an alternator object that alternates between two values.
343 *
344 * <p>Example usage in a Velocity template:
345 *
346 * <code><pre>
347 * <table>
348 * $formatter.makeAlternator("rowcolor", "#c0c0c0", "#e0e0e0")
349 * #foreach $item in $items
350 * #begin
351 * <tr><td bgcolor="$rowcolor">$item.Name</td></tr>
352 * $rowcolor.alternate()
353 * #end
354 * </table>
355 * </pre></code>
356 *
357 * @param name The name for the alternator int the context.
358 * @param alt1 The first alternate.
359 * @param alt2 The second alternate.
360 * @return The newly created instance.
361 */
362 public String makeAlternator(String name,
363 String alt1,
364 String alt2)
365 {
366 String[] alternates = { alt1, alt2 };
367 context.put(name, new VelocityAlternator(alternates));
368 return "";
369 }
370
371 /**
372 * Makes an alternator object that alternates between three
373 * values.
374 * @param name
375 * @param alt1
376 * @param alt2
377 * @param alt3
378 * @return alternated object.
379 *
380 * @see #makeAlternator(String name, String alt1, String alt2)
381 */
382 public String makeAlternator(String name,
383 String alt1,
384 String alt2,
385 String alt3)
386 {
387 String[] alternates = { alt1, alt2, alt3 };
388 context.put(name, new VelocityAlternator(alternates));
389 return "";
390 }
391
392 /**
393 * Makes an alternator object that alternates between four values.
394 * @param name
395 * @param alt1
396 * @param alt2
397 * @param alt3
398 * @param alt4
399 * @return Alternated object.
400 *
401 * @see #makeAlternator(String name, String alt1, String alt2)
402 */
403 public String makeAlternator(String name, String alt1, String alt2,
404 String alt3, String alt4)
405 {
406 String[] alternates = { alt1, alt2, alt3, alt4 };
407 context.put(name, new VelocityAlternator(alternates));
408 return "";
409 }
410
411 /**
412 * Makes an alternator object that alternates between two values
413 * automatically.
414 * @param name
415 * @param alt1
416 * @param alt2
417 * @return Alternated object.
418 *
419 * @see #makeAlternator(String name, String alt1, String alt2)
420 */
421 public String makeAutoAlternator(String name, String alt1, String alt2)
422 {
423 String[] alternates = { alt1, alt2 };
424 context.put(name, new VelocityAutoAlternator(alternates));
425 return "";
426 }
427
428 /**
429 * Returns a default value if the object passed is null.
430 * @param o
431 * @param dflt
432 * @return Object or default value when object is null.
433 */
434 public Object isNull(Object o, Object dflt)
435 {
436 if ( o == null )
437 {
438 return dflt;
439 }
440 else
441 {
442 return o;
443 }
444 }
445 }