%line | %branch | |||||||||
---|---|---|---|---|---|---|---|---|---|---|
org.apache.commons.jelly.tags.fmt.FormatDateTag |
|
|
1 | /* |
|
2 | * Copyright 2002,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 | package org.apache.commons.jelly.tags.fmt; |
|
17 | ||
18 | import org.apache.commons.jelly.JellyTagException; |
|
19 | import org.apache.commons.jelly.XMLOutput; |
|
20 | import org.apache.commons.jelly.Tag; |
|
21 | import org.apache.commons.jelly.TagSupport; |
|
22 | import org.apache.commons.jelly.expression.Expression; |
|
23 | ||
24 | import org.xml.sax.SAXException; |
|
25 | ||
26 | import java.text.DateFormat; |
|
27 | import java.text.SimpleDateFormat; |
|
28 | import java.util.Date; |
|
29 | import java.util.Locale; |
|
30 | import java.util.TimeZone; |
|
31 | ||
32 | ||
33 | /** |
|
34 | * Support for tag handlers for <formatDate>, the date and time formatting |
|
35 | * tag in JSTL. |
|
36 | * @author <a href="mailto:willievu@yahoo.com">Willie Vu</a> |
|
37 | * @version $Revision: 1.5 $ |
|
38 | * @task i18n exception message |
|
39 | */ |
|
40 | public class FormatDateTag extends TagSupport { |
|
41 | ||
42 | private static final String DEFAULT = "default"; |
|
43 | private static final String SHORT = "short"; |
|
44 | private static final String MEDIUM = "medium"; |
|
45 | private static final String LONG = "long"; |
|
46 | private static final String FULL = "full"; |
|
47 | ||
48 | private static final String DATE = "date"; |
|
49 | private static final String TIME = "time"; |
|
50 | private static final String DATETIME = "both"; |
|
51 | ||
52 | /** Holds value of property value. */ |
|
53 | private Expression value; |
|
54 | ||
55 | /** Holds value of property type. */ |
|
56 | private Expression type; |
|
57 | ||
58 | /** Holds value of property dataStyle. */ |
|
59 | private Expression dateStyle; |
|
60 | ||
61 | /** Holds value of property timeStyle. */ |
|
62 | private Expression timeStyle; |
|
63 | ||
64 | /** Holds value of property pattern. */ |
|
65 | private Expression pattern; |
|
66 | ||
67 | /** Holds value of property timeZone. */ |
|
68 | private Expression timeZone; |
|
69 | ||
70 | /** Holds value of property var. */ |
|
71 | private String var; |
|
72 | ||
73 | /** Holds value of property scope. */ |
|
74 | private String scope; |
|
75 | ||
76 | /** Evaluated type */ |
|
77 | private String etype; |
|
78 | /** Evaluated dateStyle */ |
|
79 | private String edateStyle; |
|
80 | /** Evaluated timeStyle */ |
|
81 | private String etimeStyle; |
|
82 | ||
83 | /** Creates a new instance of FormatDateTag */ |
|
84 | 0 | public FormatDateTag() { |
85 | 0 | } |
86 | ||
87 | /** |
|
88 | * Evaluates this tag after all the tags properties have been initialized. |
|
89 | * |
|
90 | */ |
|
91 | public void doTag(XMLOutput output) throws JellyTagException { |
|
92 | ||
93 | 0 | if (scope != null && var == class="keyword">null) { |
94 | 0 | throw new JellyTagException( |
95 | "If 'scope' is specified, 'var' must be defined for this tag" ); |
|
96 | } |
|
97 | ||
98 | 0 | Object valueInput = null; |
99 | 0 | if (this.value != null) { |
100 | 0 | valueInput = this.value.evaluate(context); |
101 | } |
|
102 | ||
103 | 0 | Date date = null; |
104 | 0 | if (valueInput != null && valueInput instanceof Date) { |
105 | 0 | date = (Date) valueInput; |
106 | } |
|
107 | ||
108 | 0 | if (date == null && var != class="keyword">null) { |
109 | 0 | if (scope != null) { |
110 | 0 | context.removeVariable(var, scope); |
111 | } |
|
112 | else { |
|
113 | 0 | context.removeVariable(var); |
114 | } |
|
115 | } |
|
116 | ||
117 | 0 | etype = DATE; |
118 | 0 | if (this.type != null) { |
119 | 0 | etype = (String) this.type.evaluate(context); |
120 | } |
|
121 | ||
122 | 0 | edateStyle = DEFAULT; |
123 | 0 | if (this.dateStyle != null) { |
124 | 0 | edateStyle = (String) this.dateStyle.evaluate(context); |
125 | } |
|
126 | ||
127 | 0 | etimeStyle = DEFAULT; |
128 | 0 | if (this.timeStyle != null) { |
129 | 0 | etimeStyle = (String) this.timeStyle.evaluate(context); |
130 | } |
|
131 | ||
132 | 0 | String epattern = null; |
133 | 0 | if (this.pattern != null) { |
134 | 0 | epattern = (String) this.pattern.evaluate(context); |
135 | } |
|
136 | ||
137 | 0 | Object etimeZone = null; |
138 | 0 | if (this.timeZone != null) { |
139 | 0 | etimeZone = this.timeZone.evaluate(context); |
140 | } |
|
141 | ||
142 | // Create formatter |
|
143 | 0 | Locale locale = SetLocaleTag.getFormattingLocale( |
144 | context, |
|
145 | this, |
|
146 | true, |
|
147 | DateFormat.getAvailableLocales()); |
|
148 | ||
149 | 0 | String formatted = null; |
150 | 0 | if (locale != null) { |
151 | 0 | DateFormat formatter = createFormatter(locale); |
152 | ||
153 | // Apply pattern, if present |
|
154 | 0 | if (pattern != null) { |
155 | try { |
|
156 | 0 | ((SimpleDateFormat) formatter).applyPattern(epattern); |
157 | 0 | } catch (ClassCastException cce) { |
158 | 0 | formatter = new SimpleDateFormat(epattern, locale); |
159 | } |
|
160 | } |
|
161 | ||
162 | // Set time zone |
|
163 | 0 | TimeZone tz = null; |
164 | 0 | if ((etimeZone instanceof String) |
165 | && ((String) etimeZone).equals("")) { |
|
166 | 0 | etimeZone = null; |
167 | } |
|
168 | 0 | if (etimeZone != null) { |
169 | 0 | if (etimeZone instanceof String) { |
170 | 0 | tz = TimeZone.getTimeZone((String) etimeZone); |
171 | 0 | } else if (etimeZone instanceof TimeZone) { |
172 | 0 | tz = (TimeZone) etimeZone; |
173 | } else { |
|
174 | 0 | throw new JellyTagException("Bad time zone"); |
175 | } |
|
176 | } else { |
|
177 | 0 | tz = TimeZoneTag.getTimeZone(context, this); |
178 | } |
|
179 | 0 | if (tz != null) { |
180 | 0 | formatter.setTimeZone(tz); |
181 | } |
|
182 | 0 | formatted = formatter.format(date); |
183 | } else { |
|
184 | // no formatting locale available, use Date.toString() |
|
185 | 0 | formatted = date.toString(); |
186 | } |
|
187 | ||
188 | 0 | if (var != null) { |
189 | 0 | if (scope != null) { |
190 | 0 | context.setVariable(var, scope, formatted); |
191 | } |
|
192 | else { |
|
193 | 0 | context.setVariable(var, formatted); |
194 | } |
|
195 | } |
|
196 | else { |
|
197 | try { |
|
198 | // write the formatted |
|
199 | 0 | output.write(formatted); |
200 | 0 | } catch (SAXException e) { |
201 | 0 | throw new JellyTagException("could not write formatted text",e); |
202 | } |
|
203 | } |
|
204 | 0 | } |
205 | ||
206 | /** Setter for property value. |
|
207 | * @param value New value of property value. |
|
208 | * |
|
209 | */ |
|
210 | public void setValue(Expression value) { |
|
211 | 0 | this.value = value; |
212 | 0 | } |
213 | ||
214 | /** Setter for property type. |
|
215 | * @param type New value of property type. |
|
216 | * |
|
217 | */ |
|
218 | public void setType(Expression type) { |
|
219 | 0 | this.type = type; |
220 | 0 | } |
221 | ||
222 | /** Setter for property dataStyle. |
|
223 | * @param dataStyle New value of property dataStyle. |
|
224 | * |
|
225 | */ |
|
226 | public void setDateStyle(Expression dateStyle) { |
|
227 | 0 | this.dateStyle = dateStyle; |
228 | 0 | } |
229 | ||
230 | /** Setter for property timeStyle. |
|
231 | * @param timeStyle New value of property timeStyle. |
|
232 | * |
|
233 | */ |
|
234 | public void setTimeStyle(Expression timeStyle) { |
|
235 | 0 | this.timeStyle = timeStyle; |
236 | 0 | } |
237 | ||
238 | /** Setter for property pattern. |
|
239 | * @param pattern New value of property pattern. |
|
240 | * |
|
241 | */ |
|
242 | public void setPattern(Expression pattern) { |
|
243 | 0 | this.pattern = pattern; |
244 | 0 | } |
245 | ||
246 | /** Setter for property timeZone. |
|
247 | * @param timeZone New value of property timeZone. |
|
248 | * |
|
249 | */ |
|
250 | public void setTimeZone(Expression timeZone) { |
|
251 | 0 | this.timeZone = timeZone; |
252 | 0 | } |
253 | ||
254 | /** Setter for property var. |
|
255 | * @param var New value of property var. |
|
256 | * |
|
257 | */ |
|
258 | public void setVar(String var) { |
|
259 | 0 | this.var = class="keyword">var; |
260 | 0 | } |
261 | ||
262 | /** Setter for property scope. |
|
263 | * @param scope New value of property scope. |
|
264 | * |
|
265 | */ |
|
266 | public void setScope(String scope) { |
|
267 | 0 | this.scope = scope; |
268 | 0 | } |
269 | ||
270 | //********************************************************************* |
|
271 | // Private utility methods |
|
272 | ||
273 | private DateFormat createFormatter(Locale loc) throws JellyTagException { |
|
274 | 0 | DateFormat formatter = null; |
275 | ||
276 | 0 | if ((etype == null) || DATE.equalsIgnoreCase(etype)) { |
277 | 0 | formatter = DateFormat.getDateInstance( |
278 | getStyle(edateStyle, "FORMAT_DATE_INVALID_DATE_STYLE"), |
|
279 | loc); |
|
280 | 0 | } else if (TIME.equalsIgnoreCase(etype)) { |
281 | 0 | formatter = DateFormat.getTimeInstance( |
282 | getStyle(etimeStyle, "FORMAT_DATE_INVALID_TIME_STYLE"), |
|
283 | loc); |
|
284 | 0 | } else if (DATETIME.equalsIgnoreCase(etype)) { |
285 | 0 | formatter = DateFormat.getDateTimeInstance( |
286 | getStyle(edateStyle, "FORMAT_DATE_INVALID_DATE_STYLE"), |
|
287 | getStyle(etimeStyle, "FORMAT_DATE_INVALID_TIME_STYLE"), |
|
288 | loc); |
|
289 | } else { |
|
290 | 0 | throw new JellyTagException("Date format invalue"); |
291 | } |
|
292 | ||
293 | 0 | return formatter; |
294 | } |
|
295 | ||
296 | /* |
|
297 | * Converts the given string description of a formatting style for |
|
298 | * dates and times to the corresponding java.util.DateFormat constant. |
|
299 | * |
|
300 | * @param style String description of formatting style for dates and times |
|
301 | * @param errCode Error code to throw if given style is invalid |
|
302 | * |
|
303 | * @return java.util.DateFormat constant corresponding to given style |
|
304 | * |
|
305 | * @throws JellyException if the given style is invalid |
|
306 | */ |
|
307 | public static int getStyle(String style, String errCode) |
|
308 | throws JellyTagException { |
|
309 | 0 | int ret = DateFormat.DEFAULT; |
310 | ||
311 | 0 | if (style != null) { |
312 | 0 | if (DEFAULT.equalsIgnoreCase(style)) { |
313 | 0 | ret = DateFormat.DEFAULT; |
314 | 0 | } else if (SHORT.equalsIgnoreCase(style)) { |
315 | 0 | ret = DateFormat.SHORT; |
316 | 0 | } else if (MEDIUM.equalsIgnoreCase(style)) { |
317 | 0 | ret = DateFormat.MEDIUM; |
318 | 0 | } else if (LONG.equalsIgnoreCase(style)) { |
319 | 0 | ret = DateFormat.LONG; |
320 | 0 | } else if (FULL.equalsIgnoreCase(style)) { |
321 | 0 | ret = DateFormat.FULL; |
322 | } else { |
|
323 | 0 | throw new JellyTagException("Invalid style " + errCode); |
324 | } |
|
325 | } |
|
326 | ||
327 | 0 | return ret; |
328 | } |
|
329 | ||
330 | } |
This report is generated by jcoverage, Maven and Maven JCoverage Plugin. |