Source code: org/apache/taglibs/datetime/FormatTag.java
1 /*
2 * Copyright 1999,2004 The Apache Software Foundation.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 package org.apache.taglibs.datetime;
18
19 import java.util.*;
20 import java.text.*;
21 import javax.servlet.*;
22 import javax.servlet.http.*;
23 import javax.servlet.jsp.*;
24 import javax.servlet.jsp.tagext.*;
25
26 /**
27 * JSP Tag <b>format</b>, used to format a Date for display.
28 * <p>
29 * The Date as a long in milliseconds is obtained from the body of the tag.
30 * <p>
31 * Uses the optional attribute <b>pattern</b> as the time pattern
32 * string to use when formatting the Date.
33 * <p>
34 * The optional attribute <b>timeZone</b> can be set to the id of
35 * a timeZone script varaible so that the Date if adjusted for
36 * that timeZone.
37 * <p>
38 * If the optional attribute <b>locale</b> is true, the Date
39 * is formatted for the clients locale if known.
40 * <p>
41 * The optional attribute <b>date</b> can be set to a
42 * Date object using a runtime expression value. If set,
43 * date will be used instead of the tag body.
44 * <p>
45 * The optional attribute <b>default</b> can be set to a
46 * default string to output if the date object doesn't exist
47 * or the tag body is not a valid date. If no default is set,
48 * the string "Invalid Date" is output.
49 * <p>
50 * The optional attribute <b>localeRef</b> can be used to specify
51 * the name of a page, session, application, or request scope attribute
52 * of type java.util.Locale to use.
53 * <p>
54 * JSP Tag Lib Descriptor
55 * <p><pre>
56 * <name>format</name>
57 * <tagclass>org.apache.taglibs.datetime.FormatTag</tagclass>
58 * <bodycontent>JSP</bodycontent>
59 * <info>Formats a date for output.</info>
60 * <attribute>
61 * <name>pattern</name>
62 * <required>false</required>
63 * <rtexprvalue>false</rtexprvalue>
64 * </attribute>
65 * <attribute>
66 * <name>patternId</name>
67 * <required>false</required>
68 * <rtexprvalue>false</rtexprvalue>
69 * </attribute>
70 * <attribute>
71 * <name>timeZone</name>
72 * <required>false</required>
73 * <rtexprvalue>false</rtexprvalue>
74 * </attribute>
75 * <attribute>
76 * <name>locale</name>
77 * <required>false</required>
78 * <rtexprvalue>false</rtexprvalue>
79 * </attribute>
80 * <attribute>
81 * <name>date</name>
82 * <required>false</required>
83 * <rtexprvalue>true</rtexprvalue>
84 * </attribute>
85 * <attribute>
86 * <name>default</name>
87 * <required>false</required>
88 * <rtexprvalue>false</rtexprvalue>
89 * </attribute>
90 * <attribute>
91 * <name>localeRef</name>
92 * <required>false</required>
93 * <rtexprvalue>false</rtexprvalue>
94 * </attribute>
95 * <attribute>
96 * <name>symbolsRef</name>
97 * <required>false</required>
98 * <rtexprvalue>false</rtexprvalue>
99 * </attribute>
100 * </pre>
101 *
102 * @author Glenn Nielsen
103 * @author Mark Femal
104 */
105
106 public class FormatTag extends BodyTagSupport
107 {
108
109 // format tag attributes
110
111 // Optional attribute, use users locale if known when formatting date
112 private boolean locale_flag = false;
113 // Optional attribute, time pattern string to use when formatting date
114 private String pattern = null;
115 // Optional attribute, name of script variable to use as pattern
116 private String patternid = null;
117 // Optional attribute, timeZone script variable id to use when formatting date
118 private String timeZone_string;
119 // Optional attribute, date object from rtexprvalue
120 private Date date = null;
121 // Optional attribute, the default text if the tag body or date given is invalid/null
122 private String default_text = "Invalid Date";
123 // Optional attribute, the name of an attribute which contains the Locale
124 private String localeRef = null;
125 // Optional attribute, name of script variable to use as date symbols source
126 private String symbolsRef = null;
127
128 // format tag invocation variables
129
130 // The symbols object
131 private DateFormatSymbols symbols = null;
132 // The date to be formatted an output by tag
133 private Date output_date = null;
134
135 /**
136 * Method called at start of tag, always returns EVAL_BODY_TAG
137 *
138 * @return EVAL_BODY_TAG
139 */
140 public final int doStartTag() throws JspException
141 {
142 output_date = date;
143 return EVAL_BODY_TAG;
144 }
145
146 /**
147 * Method called at end of format tag body.
148 *
149 * @return SKIP_BODY
150 */
151 public final int doAfterBody() throws JspException
152 {
153 // Use the body of the tag as input for the date
154 BodyContent body = getBodyContent();
155 String s = body.getString().trim();
156 // Clear the body since we will output only the formatted date
157 body.clearBody();
158 if( output_date == null ) {
159 long time;
160 try {
161 time = Long.valueOf(s).longValue();
162 output_date = new Date(time);
163 } catch(NumberFormatException nfe) {
164 }
165 }
166
167 return SKIP_BODY;
168 }
169
170 /**
171 * Method called at end of Tag
172 *
173 * @return EVAL_PAGE
174 */
175 public final int doEndTag() throws JspException
176 {
177 String date_formatted = default_text;
178
179 if (output_date != null) {
180 // Get the pattern to use
181 SimpleDateFormat sdf;
182 String pat = pattern;
183
184 if (pat == null && patternid != null) {
185 Object attr = pageContext.findAttribute(patternid);
186 if (attr != null)
187 pat = attr.toString();
188 }
189
190 if (pat == null) {
191 sdf = new SimpleDateFormat();
192 pat = sdf.toPattern();
193 }
194
195 // Get a DateFormatSymbols
196 if (symbolsRef != null) {
197 symbols = (DateFormatSymbols) pageContext.findAttribute(symbolsRef);
198 if (symbols == null) {
199 throw new JspException(
200 "datetime format tag could not find dateFormatSymbols for symbolsRef \"" +
201 symbolsRef + "\".");
202 }
203 }
204
205 // Get a SimpleDateFormat using locale if necessary
206 if (localeRef != null) {
207 Locale locale = (Locale) pageContext.findAttribute(localeRef);
208 if (locale == null) {
209 throw new JspException(
210 "datetime format tag could not find locale for localeRef \"" +
211 localeRef + "\".");
212 }
213
214 sdf = new SimpleDateFormat(pat, locale);
215 } else if (locale_flag) {
216 sdf = new SimpleDateFormat(pat,
217 (Locale) pageContext.getRequest().getLocale());
218 } else if (symbols != null) {
219 sdf = new SimpleDateFormat(pat,
220 symbols);
221 } else {
222 sdf = new SimpleDateFormat(pat);
223 }
224
225 // See if there is a timeZone
226 if (timeZone_string != null) {
227 TimeZone timeZone =
228 (TimeZone) pageContext.getAttribute(timeZone_string,
229 PageContext.SESSION_SCOPE);
230 if (timeZone == null) {
231 throw new JspTagException("Datetime format tag timeZone " +
232 "script variable \"" + timeZone_string +
233 " \" does not exist");
234 }
235 sdf.setTimeZone(timeZone);
236 }
237
238 // Format the date for display
239 date_formatted = sdf.format(output_date);
240 }
241
242 try {
243 pageContext.getOut().write(date_formatted);
244 } catch (Exception e) {
245 throw new JspException("IO Error: " + e.getMessage());
246 }
247
248 return EVAL_PAGE;
249 }
250
251 public void release()
252 {
253 super.release();
254 locale_flag = false;
255 pattern = null;
256 patternid = null;
257 date = null;
258 localeRef = null;
259 symbolsRef = null;
260 symbols = null;
261 }
262
263 /**
264 * Locale flag, if set to true, format date
265 * for client's preferred locale if known.
266 *
267 * @param boolean use users locale, true or false
268 */
269 public final void setLocale(boolean flag)
270 {
271 locale_flag = flag;
272 }
273
274 /**
275 * Set the time zone to use when formatting date.
276 *
277 * Value must be the name of a <b>timeZone</b> tag script
278 * variable ID.
279 *
280 * @param String name of timeZone to use
281 */
282 public final void setTimeZone(String tz)
283 {
284 timeZone_string = tz;
285 }
286
287 /**
288 * Set the pattern to use when formatting Date.
289 *
290 * @param String SimpleDateFormat style time pattern format string
291 */
292 public final void setPattern(String str)
293 {
294 pattern = str;
295 }
296
297 /**
298 * Set the pattern to use when parsing Date using a script variable
299 * attribute.
300 *
301 * @param String name of script variable attribute id
302 */
303 public final void setPatternId(String str)
304 {
305 patternid = str;
306 }
307
308 /**
309 * Set the date to use (overrides tag body) for formatting
310 *
311 * @param Date to use for formatting (could be null)
312 */
313 public final void setDate(Date date)
314 {
315 this.date = date;
316 }
317
318 /**
319 * Set the default text if an invalid date or no tag body is given
320 *
321 * @param String to use as default text
322 */
323 public final void setDefault(String default_text)
324 {
325 this.default_text = default_text;
326 }
327
328 /**
329 * Provides a key to search the page context for in order to get the
330 * java.util.Locale to use.
331 *
332 * @param String name of locale attribute to use
333 */
334 public void setLocaleRef(String value)
335 {
336 localeRef = value;
337 }
338
339 /**
340 * Provides a key to search the page context for in order to get the
341 * java.text.DateFormatSymbols to use
342 *
343 * @param symbolsRef
344 */
345 public void setSymbolsRef(String symbolsRef) throws JspException
346 {
347 this.symbolsRef = symbolsRef;
348 }
349 }