View Javadoc

1   /*
2    * $Id: WriteTag.java 421129 2006-07-12 05:13:54Z wsmoak $
3    *
4    * Copyright 1999-2004 The Apache Software Foundation.
5    *
6    * Licensed under the Apache License, Version 2.0 (the "License");
7    * you may not use this file except in compliance with the License.
8    * You may obtain a copy of the License at
9    *
10   *      http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  package org.apache.struts.taglib.bean;
19  
20  import org.apache.struts.taglib.TagUtils;
21  import org.apache.struts.util.MessageResources;
22  
23  import javax.servlet.jsp.JspException;
24  import javax.servlet.jsp.tagext.TagSupport;
25  
26  import java.math.BigDecimal;
27  import java.math.BigInteger;
28  
29  import java.text.DecimalFormat;
30  import java.text.Format;
31  import java.text.NumberFormat;
32  import java.text.SimpleDateFormat;
33  
34  import java.util.Locale;
35  
36  /***
37   * Tag that retrieves the specified property of the specified bean, converts
38   * it to a String representation (if necessary), and writes it to the current
39   * output stream, optionally filtering characters that are sensitive in HTML.
40   *
41   * @version $Rev: 421129 $ $Date: 2004-10-16 12:38:42 -0400 (Sat, 16 Oct 2004)
42   *          $
43   */
44  public class WriteTag extends TagSupport {
45      /***
46       * The key to search default format string for java.sql.Timestamp in
47       * resources.
48       */
49      public static final String SQL_TIMESTAMP_FORMAT_KEY =
50          "org.apache.struts.taglib.bean.format.sql.timestamp";
51  
52      /***
53       * The key to search default format string for java.sql.Date in
54       * resources.
55       */
56      public static final String SQL_DATE_FORMAT_KEY =
57          "org.apache.struts.taglib.bean.format.sql.date";
58  
59      /***
60       * The key to search default format string for java.sql.Time in
61       * resources.
62       */
63      public static final String SQL_TIME_FORMAT_KEY =
64          "org.apache.struts.taglib.bean.format.sql.time";
65  
66      /***
67       * The key to search default format string for java.util.Date in
68       * resources.
69       */
70      public static final String DATE_FORMAT_KEY =
71          "org.apache.struts.taglib.bean.format.date";
72  
73      /***
74       * The key to search default format string for int (byte, short, etc.) in
75       * resources.
76       */
77      public static final String INT_FORMAT_KEY =
78          "org.apache.struts.taglib.bean.format.int";
79  
80      /***
81       * The key to search default format string for float (double, BigDecimal)
82       * in resources.
83       */
84      public static final String FLOAT_FORMAT_KEY =
85          "org.apache.struts.taglib.bean.format.float";
86  
87      /***
88       * The message resources for this package.
89       */
90      protected static MessageResources messages =
91          MessageResources.getMessageResources(
92              "org.apache.struts.taglib.bean.LocalStrings");
93  
94      // ------------------------------------------------------------- Properties
95  
96      /***
97       * Filter the rendered output for characters that are sensitive in HTML?
98       */
99      protected boolean filter = true;
100 
101     /***
102      * Should we ignore missing beans and simply output nothing?
103      */
104     protected boolean ignore = false;
105 
106     /***
107      * Name of the bean that contains the data we will be rendering.
108      */
109     protected String name = null;
110 
111     /***
112      * Name of the property to be accessed on the specified bean.
113      */
114     protected String property = null;
115 
116     /***
117      * The scope to be searched to retrieve the specified bean.
118      */
119     protected String scope = null;
120 
121     /***
122      * The format string to be used as format to convert value to String.
123      */
124     protected String formatStr = null;
125 
126     /***
127      * The key to search format string in applciation resources
128      */
129     protected String formatKey = null;
130 
131     /***
132      * The session scope key under which our Locale is stored.
133      */
134     protected String localeKey = null;
135 
136     /***
137      * The servlet context attribute key for our resources.
138      */
139     protected String bundle = null;
140 
141     public boolean getFilter() {
142         return (this.filter);
143     }
144 
145     public void setFilter(boolean filter) {
146         this.filter = filter;
147     }
148 
149     public boolean getIgnore() {
150         return (this.ignore);
151     }
152 
153     public void setIgnore(boolean ignore) {
154         this.ignore = ignore;
155     }
156 
157     public String getName() {
158         return (this.name);
159     }
160 
161     public void setName(String name) {
162         this.name = name;
163     }
164 
165     public String getProperty() {
166         return (this.property);
167     }
168 
169     public void setProperty(String property) {
170         this.property = property;
171     }
172 
173     public String getScope() {
174         return (this.scope);
175     }
176 
177     public void setScope(String scope) {
178         this.scope = scope;
179     }
180 
181     public String getFormat() {
182         return (this.formatStr);
183     }
184 
185     public void setFormat(String formatStr) {
186         this.formatStr = formatStr;
187     }
188 
189     public String getFormatKey() {
190         return (this.formatKey);
191     }
192 
193     public void setFormatKey(String formatKey) {
194         this.formatKey = formatKey;
195     }
196 
197     public String getLocale() {
198         return (this.localeKey);
199     }
200 
201     public void setLocale(String localeKey) {
202         this.localeKey = localeKey;
203     }
204 
205     public String getBundle() {
206         return (this.bundle);
207     }
208 
209     public void setBundle(String bundle) {
210         this.bundle = bundle;
211     }
212 
213     // --------------------------------------------------------- Public Methods
214 
215     /***
216      * Process the start tag.
217      *
218      * @throws JspException if a JSP exception has occurred
219      */
220     public int doStartTag() throws JspException {
221         // Look up the requested bean (if necessary)
222         if (ignore) {
223             if (TagUtils.getInstance().lookup(pageContext, name, scope)
224                 == null) {
225                 return (SKIP_BODY); // Nothing to output
226             }
227         }
228 
229         // Look up the requested property value
230         Object value =
231             TagUtils.getInstance().lookup(pageContext, name, property, scope);
232 
233         if (value == null) {
234             return (SKIP_BODY); // Nothing to output
235         }
236 
237         // Convert value to the String with some formatting
238         String output = formatValue(value);
239 
240         // Print this property value to our output writer, suitably filtered
241         if (filter) {
242             TagUtils.getInstance().write(pageContext,
243                 TagUtils.getInstance().filter(output));
244         } else {
245             TagUtils.getInstance().write(pageContext, output);
246         }
247 
248         // Continue processing this page
249         return (SKIP_BODY);
250     }
251 
252     /***
253      * Retrieve format string from message bundle and return null if message
254      * not found or message string.
255      *
256      * @param formatKey value to use as key to search message in bundle
257      * @throws JspException if a JSP exception has occurred
258      */
259     protected String retrieveFormatString(String formatKey)
260         throws JspException {
261         String result =
262             TagUtils.getInstance().message(pageContext, this.bundle,
263                 this.localeKey, formatKey);
264 
265         if ((result != null)
266             && !(result.startsWith("???") && result.endsWith("???"))) {
267             return result;
268         } else {
269             return null;
270         }
271     }
272 
273     /***
274      * Format value according to specified format string (as tag attribute or
275      * as string from message resources) or to current user locale.
276      *
277      * When a format string is retrieved from the message resources,
278      * <code>applyLocalizedPattern</code> is used. For more about localized
279      * patterns, see
280      * <http://www.dei.unipd.it/corsi/fi2ae-docs/source/jdk1.1.7/src/java/text/resources/>.
281      * (To obtain the correct value for some characters, you may need to view
282      * the file in a hex editor and then use the Unicode escape form in the
283      * property resources file.)
284      *
285      * @param valueToFormat value to process and convert to String
286      * @throws JspException if a JSP exception has occurred
287      */
288     protected String formatValue(Object valueToFormat)
289         throws JspException {
290         Format format = null;
291         Object value = valueToFormat;
292         Locale locale =
293             TagUtils.getInstance().getUserLocale(pageContext, this.localeKey);
294         boolean formatStrFromResources = false;
295         String formatString = formatStr;
296 
297         // Return String object as is.
298         if (value instanceof java.lang.String) {
299             return (String) value;
300         } else {
301             // Try to retrieve format string from resources by the key from
302             // formatKey.
303             if ((formatString == null) && (formatKey != null)) {
304                 formatString = retrieveFormatString(this.formatKey);
305 
306                 if (formatString != null) {
307                     formatStrFromResources = true;
308                 }
309             }
310 
311             // Prepare format object for numeric values.
312             if (value instanceof Number) {
313                 if (formatString == null) {
314                     if ((value instanceof Byte) || (value instanceof Short)
315                         || (value instanceof Integer)
316                         || (value instanceof Long)
317                         || (value instanceof BigInteger)) {
318                         formatString = retrieveFormatString(INT_FORMAT_KEY);
319                     } else if ((value instanceof Float)
320                         || (value instanceof Double)
321                         || (value instanceof BigDecimal)) {
322                         formatString = retrieveFormatString(FLOAT_FORMAT_KEY);
323                     }
324 
325                     if (formatString != null) {
326                         formatStrFromResources = true;
327                     }
328                 }
329 
330                 if (formatString != null) {
331                     try {
332                         format = NumberFormat.getNumberInstance(locale);
333 
334                         if (formatStrFromResources) {
335                             ((DecimalFormat) format).applyLocalizedPattern(
336                                 formatString);
337                         } else {
338                             ((DecimalFormat) format).applyPattern(formatString);
339                         }
340                     } catch (IllegalArgumentException e) {
341                         JspException ex =
342                             new JspException(messages.getMessage(
343                                     "write.format", formatString));
344 
345                         TagUtils.getInstance().saveException(pageContext, ex);
346                         throw ex;
347                     }
348                 }
349             } else if (value instanceof java.util.Date) {
350                 if (formatString == null) {
351                     if (value instanceof java.sql.Timestamp) {
352                         formatString =
353                             retrieveFormatString(SQL_TIMESTAMP_FORMAT_KEY);
354                     } else if (value instanceof java.sql.Date) {
355                         formatString =
356                             retrieveFormatString(SQL_DATE_FORMAT_KEY);
357                     } else if (value instanceof java.sql.Time) {
358                         formatString =
359                             retrieveFormatString(SQL_TIME_FORMAT_KEY);
360                     } else if (value instanceof java.util.Date) {
361                         formatString = retrieveFormatString(DATE_FORMAT_KEY);
362                     }
363                 }
364 
365                 if (formatString != null) {
366                     format = new SimpleDateFormat(formatString, locale);
367                 }
368             }
369         }
370 
371         if (format != null) {
372             return format.format(value);
373         } else {
374             return value.toString();
375         }
376     }
377 
378     /***
379      * Release all allocated resources.
380      */
381     public void release() {
382         super.release();
383         filter = true;
384         ignore = false;
385         name = null;
386         property = null;
387         scope = null;
388         formatStr = null;
389         formatKey = null;
390         localeKey = null;
391         bundle = null;
392     }
393 }