001/** 002 * 003 * Copyright (c) 2014, the Railo Company Ltd. All rights reserved. 004 * 005 * This library is free software; you can redistribute it and/or 006 * modify it under the terms of the GNU Lesser General Public 007 * License as published by the Free Software Foundation; either 008 * version 2.1 of the License, or (at your option) any later version. 009 * 010 * This library is distributed in the hope that it will be useful, 011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 013 * Lesser General Public License for more details. 014 * 015 * You should have received a copy of the GNU Lesser General Public 016 * License along with this library. If not, see <http://www.gnu.org/licenses/>. 017 * 018 **/ 019package org.apache.taglibs.datetime; 020 021import java.text.DateFormatSymbols; 022import java.text.SimpleDateFormat; 023import java.util.Date; 024import java.util.Locale; 025import java.util.TimeZone; 026 027import javax.servlet.jsp.JspException; 028import javax.servlet.jsp.JspTagException; 029import javax.servlet.jsp.PageContext; 030import javax.servlet.jsp.tagext.BodyContent; 031import javax.servlet.jsp.tagext.BodyTagSupport; 032 033public final class FormatTag extends BodyTagSupport { 034 035 // format tag attributes 036 037 // Optional attribute, use users locale if known when formatting date 038 private boolean locale_flag = false; 039 // Optional attribute, time pattern string to use when formatting date 040 private String pattern = null; 041 // Optional attribute, name of script variable to use as pattern 042 private String patternid = null; 043 // Optional attribute, timeZone script variable id to use when formatting date 044 private String timeZone_string; 045 // Optional attribute, date object from rtexprvalue 046 private Date date = null; 047 // Optional attribute, the default text if the tag body or date given is invalid/null 048 private String default_text = "Invalid Date"; 049 // Optional attribute, the name of an attribute which contains the Locale 050 private String localeRef = null; 051 // Optional attribute, name of script variable to use as date symbols source 052 private String symbolsRef = null; 053 054 // format tag invocation variables 055 056 // The symbols object 057 private DateFormatSymbols symbols = null; 058 // The date to be formatted an output by tag 059 private Date output_date = null; 060 061 /** 062 * Method called at start of tag, always returns EVAL_BODY_TAG 063 * 064 * @return EVAL_BODY_TAG 065 */ 066 public final int doStartTag() throws JspException 067 { 068 output_date = date; 069 return EVAL_BODY_TAG; 070 } 071 072 /** 073 * Method called at end of format tag body. 074 * 075 * @return SKIP_BODY 076 */ 077 public final int doAfterBody() throws JspException 078 { 079 // Use the body of the tag as input for the date 080 BodyContent body = getBodyContent(); 081 String s = body.getString().trim(); 082 // Clear the body since we will output only the formatted date 083 body.clearBody(); 084 if( output_date == null ) { 085 long time; 086 try { 087 time = Long.valueOf(s).longValue(); 088 output_date = new Date(time); 089 } catch(NumberFormatException nfe) { 090 } 091 } 092 093 return SKIP_BODY; 094 } 095 096 /** 097 * Method called at end of Tag 098 * 099 * @return EVAL_PAGE 100 */ 101 public final int doEndTag() throws JspException 102 { 103 String date_formatted = default_text; 104 105 if (output_date != null) { 106 // Get the pattern to use 107 SimpleDateFormat sdf; 108 String pat = pattern; 109 110 if (pat == null && patternid != null) { 111 Object attr = pageContext.findAttribute(patternid); 112 if (attr != null) 113 pat = attr.toString(); 114 } 115 116 if (pat == null) { 117 sdf = new SimpleDateFormat(); 118 pat = sdf.toPattern(); 119 } 120 121 // Get a DateFormatSymbols 122 if (symbolsRef != null) { 123 symbols = (DateFormatSymbols) pageContext.findAttribute(symbolsRef); 124 if (symbols == null) { 125 throw new JspException( 126 "datetime format tag could not find dateFormatSymbols for symbolsRef \"" + 127 symbolsRef + "\"."); 128 } 129 } 130 131 // Get a SimpleDateFormat using locale if necessary 132 if (localeRef != null) { 133 Locale locale = (Locale) pageContext.findAttribute(localeRef); 134 if (locale == null) { 135 throw new JspException( 136 "datetime format tag could not find locale for localeRef \"" + 137 localeRef + "\"."); 138 } 139 140 sdf = new SimpleDateFormat(pat, locale); 141 } else if (locale_flag) { 142 sdf = new SimpleDateFormat(pat, 143 pageContext.getRequest().getLocale()); 144 } else if (symbols != null) { 145 sdf = new SimpleDateFormat(pat, 146 symbols); 147 } else { 148 sdf = new SimpleDateFormat(pat); 149 } 150 151 // See if there is a timeZone 152 if (timeZone_string != null) { 153 TimeZone timeZone = 154 (TimeZone) pageContext.getAttribute(timeZone_string, 155 PageContext.SESSION_SCOPE); 156 if (timeZone == null) { 157 throw new JspTagException("Datetime format tag timeZone " + 158 "script variable \"" + timeZone_string + 159 " \" does not exist"); 160 } 161 sdf.setTimeZone(timeZone); 162 } 163 164 // Format the date for display 165 date_formatted = sdf.format(output_date); 166 } 167 168 try { 169 pageContext.getOut().write(date_formatted); 170 } catch (Exception e) { 171 throw new JspException("IO Error: " + e.getMessage()); 172 } 173 174 return EVAL_PAGE; 175 } 176 177 public void release() 178 { 179 //lucee.print.ln("release FormatTag"); 180 super.release(); 181 locale_flag = false; 182 pattern = null; 183 patternid = null; 184 date = null; 185 localeRef = null; 186 symbolsRef = null; 187 symbols = null; 188 } 189 190 /** 191 * Locale flag, if set to true, format date 192 * for client's preferred locale if known. 193 * 194 * @param boolean use users locale, true or false 195 */ 196 public final void setLocale(short flag) 197 { 198 //locale_flag = flag; 199 } 200 201 /** 202 * Set the time zone to use when formatting date. 203 * 204 * Value must be the name of a <b>timeZone</b> tag script 205 * variable ID. 206 * 207 * @param String name of timeZone to use 208 */ 209 public final void setTimeZone(String tz) 210 { 211 timeZone_string = tz; 212 } 213 214 /** 215 * Set the pattern to use when formatting Date. 216 * 217 * @param String SimpleDateFormat style time pattern format string 218 */ 219 public final void setPattern(String str) 220 { 221 pattern = str; 222 } 223 224 /** 225 * Set the pattern to use when parsing Date using a script variable 226 * attribute. 227 * 228 * @param String name of script variable attribute id 229 */ 230 public final void setPatternId(String str) 231 { 232 patternid = str; 233 } 234 235 /** 236 * Set the date to use (overrides tag body) for formatting 237 * 238 * @param Date to use for formatting (could be null) 239 */ 240 public final void setDate(Date date) 241 { 242 this.date = date; 243 } 244 245 /** 246 * Set the default text if an invalid date or no tag body is given 247 * 248 * @param String to use as default text 249 */ 250 public final void setDefault(String default_text) 251 { 252 this.default_text = default_text; 253 } 254 255 /** 256 * Provides a key to search the page context for in order to get the 257 * java.util.Locale to use. 258 * 259 * @param String name of locale attribute to use 260 */ 261 public void setLocaleRef(String value) 262 { 263 localeRef = value; 264 } 265 266 /** 267 * Provides a key to search the page context for in order to get the 268 * java.text.DateFormatSymbols to use 269 * 270 * @param symbolsRef 271 */ 272 public void setSymbolsRef(String symbolsRef) { 273 this.symbolsRef = symbolsRef; 274 } 275 276}