001: /**
002: * Copyright 2006 Webmedia Group Ltd.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: **/package org.araneaframework.uilib.form.control;
016:
017: import java.sql.Timestamp;
018: import java.util.Calendar;
019: import org.araneaframework.uilib.event.OnChangeEventListener;
020: import org.araneaframework.uilib.event.StandardControlEventListenerAdapter;
021: import org.araneaframework.uilib.form.FormElementContext;
022: import org.araneaframework.uilib.support.UiLibMessages;
023: import org.araneaframework.uilib.util.MessageUtil;
024:
025: /**
026: * This class represents a control that has both date and time.
027: *
028: * @author Jevgeni Kabanov (ekabanov <i>at</i> araneaframework <i>dot</i> org)
029: */
030: public class DateTimeControl extends BaseControl {
031: //*******************************************************************
032: // FIELDS
033: //*******************************************************************
034: /** @since 1.0.3 */
035: protected StandardControlEventListenerAdapter eventHelper = new StandardControlEventListenerAdapter();
036:
037: protected DateControl dateControl;
038: protected TimeControl timeControl;
039:
040: //*******************************************************************
041: // CONSTRUCTORS
042: //*******************************************************************
043:
044: /**
045: * Creates both {@link TimeControl}and {@link DateControl}with default parameters.
046: */
047: public DateTimeControl() {
048: dateControl = new DateControl();
049: timeControl = new TimeControl();
050: }
051:
052: /**
053: * Creates {@link DateTimeControl} consisting of specified {@link DateControl}
054: * and {@link TimeControl}.
055: *
056: * @since 1.0.3
057: */
058: public DateTimeControl(DateControl dateControl,
059: TimeControl timeControl) {
060: this .dateControl = dateControl;
061: this .timeControl = timeControl;
062: }
063:
064: /**
065: * Creates {@link TimeControl}with <code>timeFormat</code> parameter and {@link DateControl}with <code>dateFormat</code>
066: * parameter.
067: *
068: * @param dateFormat {@link java.text.SimpleDateFormat}pattern.
069: * @param timeFormat {@link java.text.SimpleDateFormat}pattern.
070: */
071: public DateTimeControl(String dateFormat, String timeFormat,
072: String defaultDateOutputFormat,
073: String defaultTimeOutputFormat) {
074: dateControl = new DateControl(dateFormat,
075: defaultDateOutputFormat);
076: timeControl = new TimeControl(timeFormat,
077: defaultTimeOutputFormat);
078: }
079:
080: //*******************************************************************
081: // PUBLIC METHODS
082: //*******************************************************************
083:
084: /**
085: * Returns "Timestamp".
086: *
087: * @return "Timestamp".
088: */
089: public String getRawValueType() {
090: return "Timestamp";
091: }
092:
093: public boolean isRead() {
094: // if date is not present, control cannot have valid value -- see comment
095: // in addTimeToDate() method
096: return dateControl.isRead();
097: }
098:
099: /**
100: * @since 1.0.3
101: */
102: public void addOnChangeEventListener(
103: OnChangeEventListener onChangeEventListener) {
104: eventHelper.addOnChangeEventListener(onChangeEventListener);
105: }
106:
107: /**
108: * @since 1.0.3
109: */
110: public void clearOnChangeEventListeners() {
111: eventHelper.clearOnChangeEventListeners();
112: }
113:
114: //*******************************************************************
115: // HELPER METHODS
116: //*******************************************************************
117:
118: /**
119: * Adds two dates assuming the first being date part and other the time. (dd.MM.yyyy and HH:mm:ss accordingly).
120: *
121: * @param date the date to add to.
122: * @param time the time to be added.
123: * @return the sum of the date and the time.
124: */
125: private Timestamp addTimeToDate(Timestamp date, Timestamp time) {
126: // if date is null, it means that date part is completely cleared
127: // and when we just return time, it means that Control now holds a
128: // bogus Date since 'Jan 01 00:00:00 EET 1970'.
129: // problem was described in task 336 and forum topic
130: // http://forum.araneaframework.org/viewtopic.php?t=128
131:
132: // date is null, discard the time
133: if (date == null)
134: return null;
135:
136: if (time == null)
137: return date;
138:
139: Calendar dateCalendar = getCalendarInstance();
140: Calendar timeCalendar = getCalendarInstance();
141: dateCalendar.setTime(date);
142: timeCalendar.setTime(time);
143: dateCalendar.set(Calendar.HOUR_OF_DAY, timeCalendar
144: .get(Calendar.HOUR_OF_DAY));
145: dateCalendar.set(Calendar.MINUTE, timeCalendar
146: .get(Calendar.MINUTE));
147: return new Timestamp(dateCalendar.getTime().getTime());
148: }
149:
150: //*********************************************************************
151: //* INTERNAL METHODS
152: //*********************************************************************
153:
154: protected void init() throws Exception {
155: super .init();
156:
157: setGlobalEventListener(eventHelper);
158:
159: addWidget("date", dateControl);
160: addWidget("time", timeControl);
161: }
162:
163: /**
164: * Used by {@link DateTimeControl#convert()} to acquire <code>Calendar</code>
165: * instance for converting <code>Date</code> and <code>Time</code> values read
166: * from request to single <code>TimeStamp</code>.
167: *
168: * @return <code>Calendar</code> using the default time zone and default locale.
169: * @since 1.0.3
170: */
171: protected Calendar getCalendarInstance() {
172: return Calendar.getInstance();
173: }
174:
175: /**
176: *
177: */
178: public void convert() {
179: dateControl.convert();
180: timeControl.convert();
181:
182: //Reading control data
183: if (getFormElementCtx().isValid() && isRead()) {
184: value = addTimeToDate(
185: (Timestamp) dateControl.getRawValue(),
186: (Timestamp) timeControl.getRawValue());
187: } else {
188: value = null;
189: }
190: }
191:
192: public void validate() {
193: if (isMandatory() && !isRead()) {
194: addError(MessageUtil.localizeAndFormat(
195: UiLibMessages.MANDATORY_FIELD, MessageUtil
196: .localize(getLabel(), getEnvironment()),
197: getEnvironment()));
198: }
199: }
200:
201: /**
202: * Returns {@link ViewModel}.
203: * @return {@link ViewModel}.
204: */
205: public Object getViewModel() throws Exception {
206: return new ViewModel();
207: }
208:
209: public void setRawValue(Object value) {
210: // mark composite control dirty
211: super .setRawValue(null);
212: dateControl.setRawValue(value);
213: timeControl.setRawValue(value);
214: }
215:
216: public void setFormElementCtx(FormElementContext formElementContext) {
217: super .setFormElementCtx(formElementContext);
218:
219: dateControl.setFormElementCtx(formElementContext);
220: timeControl.setFormElementCtx(formElementContext);
221: }
222:
223: //*********************************************************************
224: //* VIEW MODEL
225: //*********************************************************************
226:
227: /**
228: * Represents a date-time control view model.
229: * @author Jevgeni Kabanov (ekabanov <i>at</i> araneaframework <i>dot</i> org)
230: *
231: */
232: public class ViewModel extends BaseControl.ViewModel {
233: private String time;
234: private String date;
235:
236: private DateControl.ViewModel dateViewModel;
237: private TimeControl.ViewModel timeViewModel;
238:
239: private boolean hasOnChangeEventListeners;
240:
241: /**
242: * Takes an outer class snapshot.
243: */
244: public ViewModel() throws Exception {
245: dateViewModel = (DateControl.ViewModel) dateControl
246: ._getViewable().getViewModel();
247: String[] timeInnerData = (String[]) timeControl.innerData;
248: this .time = timeInnerData == null ? null : timeInnerData[0];
249:
250: timeViewModel = (TimeControl.ViewModel) timeControl
251: ._getViewable().getViewModel();
252: String[] dateInnerData = (String[]) dateControl.innerData;
253: this .date = dateInnerData == null ? null : dateInnerData[0];
254:
255: this .hasOnChangeEventListeners = eventHelper
256: .hasOnChangeEventListeners();
257: }
258:
259: /**
260: * Returns time as <code>String</code>.
261: * @return time as <code>String</code>.
262: */
263: public String getTime() {
264: return time;
265: }
266:
267: /**
268: * Returns date as <code>String</code>.
269: * @return date as <code>String</code>.
270: */
271: public String getDate() {
272: return date;
273: }
274:
275: /**
276: * @since 1.0.3
277: */
278: public boolean isOnChangeEventRegistered() {
279: return hasOnChangeEventListeners;
280: }
281:
282: public DateControl.ViewModel getDateViewModel() {
283: return dateViewModel;
284: }
285:
286: public TimeControl.ViewModel getTimeViewModel() {
287: return timeViewModel;
288: }
289: }
290: }
|