001: /*
002: * $Id: DateTimePicker.java 512578 2007-02-28 02:44:58Z musachy $
003: *
004: * Licensed to the Apache Software Foundation (ASF) under one
005: * or more contributor license agreements. See the NOTICE file
006: * distributed with this work for additional information
007: * regarding copyright ownership. The ASF licenses this file
008: * to you under the Apache License, Version 2.0 (the
009: * "License"); you may not use this file except in compliance
010: * with the License. You may obtain a copy of the License at
011: *
012: * http://www.apache.org/licenses/LICENSE-2.0
013: *
014: * Unless required by applicable law or agreed to in writing,
015: * software distributed under the License is distributed on an
016: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017: * KIND, either express or implied. See the License for the
018: * specific language governing permissions and limitations
019: * under the License.
020: */
021: package org.apache.struts2.components;
022:
023: import java.text.ParseException;
024: import java.text.SimpleDateFormat;
025: import java.util.Date;
026:
027: import javax.servlet.http.HttpServletRequest;
028: import javax.servlet.http.HttpServletResponse;
029:
030: import org.apache.commons.logging.Log;
031: import org.apache.commons.logging.LogFactory;
032: import org.apache.struts2.views.annotations.StrutsTag;
033: import org.apache.struts2.views.annotations.StrutsTagAttribute;
034:
035: import com.opensymphony.xwork2.util.ValueStack;
036:
037: /**
038: * <!-- START SNIPPET: javadoc -->
039: * <p>
040: * Renders a date/time picker in a dropdown container.
041: * </p>
042: * <p>
043: * A stand-alone DateTimePicker widget that makes it easy to select a date/time, or increment by week, month,
044: * and/or year.
045: * </p>
046: *
047: * <p>
048: * It is possible to customize the user-visible formatting with either the
049: * 'formatLength' (long, short, medium or full) or 'displayFormat' attributes. By defaulty current
050: * locale will be used.</p>
051: * </p>
052: *
053: * Syntax supported by 'displayFormat' is (http://www.unicode.org/reports/tr35/tr35-4.html#Date_Format_Patterns):-
054: * <table border="1">
055: * <tr>
056: * <td>Format</td>
057: * <td>Description</td>
058: * </tr>
059: * <tr>
060: * <td>d</td>
061: * <td>Day of the month</td>
062: * </tr>
063: * <tr>
064: * <td>D</td>
065: * <td>Day of year</td>
066: * </tr>
067: * <tr>
068: * <td>M</td>
069: * <td>Month - Use one or two for the numerical month, three for the abbreviation, or four for the full name, or 5 for the narrow name.</td>
070: * </tr>
071: * <tr>
072: * <td>h</td>
073: * <td>Hour [1-12].</td>
074: * </tr>
075: * <tr>
076: * <td>H</td>
077: * <td>Hour [0-23].</td>
078: * </tr>
079: * <tr>
080: * <td>m</td>
081: * <td>Minute. Use one or two for zero padding.</td>
082: * </tr>
083: * <tr>
084: * <td>s</td>
085: * <td>Second. Use one or two for zero padding.</td>
086: * </tr>
087: * </table>
088: *
089: * <p>
090: * The value sent to the server is
091: * typically a locale-independent value in a hidden field as defined by the name
092: * attribute. RFC3339 representation is the format used.
093: * </p>
094: *
095: * <p/>
096: *
097: * <!-- END SNIPPET: javadoc -->
098: *
099: * <b>Examples</b>
100: *
101: * <pre>
102: * <!-- START SNIPPET: expl1 -->
103: *
104: * Example 1:
105: * <s:datetimepicker name="order.date" label="Order Date" />
106: * Example 2:
107: * <s:datetimepicker name="delivery.date" label="Delivery Date" format="yyyy-MM-dd" />
108: *
109: * <!-- END SNIPPET: expl1 -->
110: * </pre>
111: * <p/>
112: *
113: * <!-- START SNIPPET: expldesc2 -->
114: *
115: * The css could be changed by using the following :-
116: *
117: * <!-- END SNIPPET: expldesc2 -->
118: *
119: * <pre>
120: * <!-- START SNIPPET: expl2 -->
121: *
122: * <s:datetimepicker name="birthday" label="Birthday" templateCss="...." />
123: *
124: * <!-- END SNIPPET: expl2 -->
125: * </pre>
126: *
127: */
128: @StrutsTag(name="datetimepicker",tldTagClass="org.apache.struts2.views.jsp.ui.DateTimePickerTag",description="Render datetimepicker")
129: public class DateTimePicker extends UIBean {
130:
131: final public static String TEMPLATE = "datetimepicker";
132: final private static SimpleDateFormat RFC3339_FORMAT = new SimpleDateFormat(
133: "yyyy-MM-dd'T'HH:mm:ss");
134: final protected static Log LOG = LogFactory
135: .getLog(DateTimePicker.class);
136:
137: protected String iconPath;
138: protected String formatLength;
139: protected String displayFormat;
140: protected String toggleType;
141: protected String toggleDuration;
142: protected String type;
143:
144: protected String displayWeeks;
145: protected String adjustWeeks;
146: protected String startDate;
147: protected String endDate;
148: protected String weekStartsOn;
149: protected String staticDisplay;
150: protected String dayWidth;
151: protected String language;
152: protected String templateCssPath;
153:
154: public DateTimePicker(ValueStack stack, HttpServletRequest request,
155: HttpServletResponse response) {
156: super (stack, request, response);
157: }
158:
159: protected String getDefaultTemplate() {
160: return TEMPLATE;
161: }
162:
163: public void evaluateParams() {
164: super .evaluateParams();
165:
166: if (displayWeeks != null)
167: addParameter("displayWeeks", findString(displayWeeks));
168: if (adjustWeeks != null)
169: addParameter("adjustWeeks", findValue(adjustWeeks,
170: Boolean.class));
171: if (startDate != null)
172: addParameter("startDate", findString(startDate));
173: if (endDate != null)
174: addParameter("endDate", findString(endDate));
175: if (weekStartsOn != null)
176: addParameter("weekStartsOn", findString(weekStartsOn));
177: if (staticDisplay != null)
178: addParameter("staticDisplay", findValue(staticDisplay,
179: Boolean.class));
180: if (dayWidth != null)
181: addParameter("dayWidth", findValue(dayWidth, Integer.class));
182: if (language != null)
183: addParameter("language", findString(language));
184: if (value != null)
185: addParameter("value", findString(value));
186: if (iconPath != null)
187: addParameter("iconPath", findString(iconPath));
188: if (formatLength != null)
189: addParameter("formatLength", findString(formatLength));
190: if (displayFormat != null)
191: addParameter("displayFormat", findString(displayFormat));
192: if (toggleType != null)
193: addParameter("toggleType", findString(toggleType));
194: if (toggleDuration != null)
195: addParameter("toggleDuration", findValue(toggleDuration,
196: Integer.class));
197: if (type != null)
198: addParameter("type", findString(type));
199: else
200: addParameter("type", "date");
201: if (templateCssPath != null)
202: addParameter("templateCssPath", findString(templateCssPath));
203:
204: // format the value to RFC 3399
205: if (parameters.containsKey("value")) {
206: parameters
207: .put("nameValue", format(parameters.get("value")));
208: } else {
209: if (name != null) {
210: String expr = name;
211: if (altSyntax()) {
212: expr = "%{" + expr + "}";
213: }
214: addParameter("nameValue", format(findValue(expr)));
215: }
216: }
217: }
218:
219: @StrutsTagAttribute(description="If true, weekly size of calendar changes to acomodate the month if false," + " 42 day format is used",type="Boolean",defaultValue="false")
220: public void setAdjustWeeks(String adjustWeeks) {
221: this .adjustWeeks = adjustWeeks;
222: }
223:
224: @StrutsTagAttribute(description="How to render the names of the days in the header(narrow, abbr or wide)",defaultValue="narrow")
225: public void setDayWidth(String dayWidth) {
226: this .dayWidth = dayWidth;
227: }
228:
229: @StrutsTagAttribute(description="Total weeks to display",type="Integer",defaultValue="6")
230: public void setDisplayWeeks(String displayWeeks) {
231: this .displayWeeks = displayWeeks;
232: }
233:
234: @StrutsTagAttribute(description="Last available date in the calendar set",type="Date",defaultValue="2941-10-12")
235: public void setEndDate(String endDate) {
236: this .endDate = endDate;
237: }
238:
239: @StrutsTagAttribute(description="First available date in the calendar set",type="Date",defaultValue="1492-10-12")
240: public void setStartDate(String startDate) {
241: this .startDate = startDate;
242: }
243:
244: @StrutsTagAttribute(description="Disable all incremental controls, must pick a date in the current display",type="Boolean",defaultValue="false")
245: public void setStaticDisplay(String staticDisplay) {
246: this .staticDisplay = staticDisplay;
247: }
248:
249: @StrutsTagAttribute(description="Adjusts the first day of the week 0==Sunday..6==Saturday",type="Integer",defaultValue="0")
250: public void setWeekStartsOn(String weekStartsOn) {
251: this .weekStartsOn = weekStartsOn;
252: }
253:
254: @StrutsTagAttribute(description="Language to display this widget in",defaultValue="brower's specified preferred language")
255: public void setLanguage(String language) {
256: this .language = language;
257: }
258:
259: @StrutsTagAttribute(description="A pattern used for the visual display of the formatted date, e.g. dd/MM/yyyy")
260: public void setDisplayFormat(String displayFormat) {
261: this .displayFormat = displayFormat;
262: }
263:
264: @StrutsTagAttribute(description="Type of formatting used for visual display. Possible values are " + "long, short, medium or full",defaultValue="short")
265: public void setFormatLength(String formatLength) {
266: this .formatLength = formatLength;
267: }
268:
269: @StrutsTagAttribute(description="Path to icon used for the dropdown")
270: public void setIconPath(String iconPath) {
271: this .iconPath = iconPath;
272: }
273:
274: @StrutsTagAttribute(description="Duration of toggle in milliseconds",type="Integer",defaultValue="100")
275: public void setToggleDuration(String toggleDuration) {
276: this .toggleDuration = toggleDuration;
277: }
278:
279: @StrutsTagAttribute(description="Defines the type of the picker on the dropdown. Possible values are 'date'" + " for a DateTimePicker, and 'time' for a timePicker",defaultValue="date")
280: public void setType(String type) {
281: this .type = type;
282: }
283:
284: @StrutsTagAttribute(description="oggle type of the dropdown. Possible values are plain,wipe,explode,fade",defaultValue="plain")
285: public void setToggleType(String toggleType) {
286: this .toggleType = toggleType;
287: }
288:
289: @StrutsTagAttribute(description="Template css path")
290: public void setTemplateCssPath(String templateCssPath) {
291: this .templateCssPath = templateCssPath;
292: }
293:
294: private String format(Object obj) {
295: if (obj == null)
296: return null;
297:
298: if (obj instanceof Date) {
299: return RFC3339_FORMAT.format((Date) obj);
300: } else {
301: // try to parse a date
302: String dateStr = obj.toString();
303: if (dateStr.equalsIgnoreCase("today"))
304: return RFC3339_FORMAT.format(new Date());
305:
306: try {
307: Date date = null;
308: if (this .displayFormat != null) {
309: SimpleDateFormat format = new SimpleDateFormat(
310: (String) getParameters().get(
311: "displayFormat"));
312: date = format.parse(dateStr);
313: return RFC3339_FORMAT.format(date);
314: } else {
315: // last resource to assume already in correct/default format
316: return dateStr;
317: }
318: } catch (ParseException e) {
319: LOG.error("Could not parse date", e);
320: return dateStr;
321: }
322: }
323: }
324:
325: }
|