KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > icesoft > faces > component > selectinputdate > SelectInputDateRenderer


1 /*
2  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
3  *
4  * "The contents of this file are subject to the Mozilla Public License
5  * Version 1.1 (the "License"); you may not use this file except in
6  * compliance with the License. You may obtain a copy of the License at
7  * http://www.mozilla.org/MPL/
8  *
9  * Software distributed under the License is distributed on an "AS IS"
10  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
11  * License for the specific language governing rights and limitations under
12  * the License.
13  *
14  * The Original Code is ICEfaces 1.5 open source software code, released
15  * November 5, 2006. The Initial Developer of the Original Code is ICEsoft
16  * Technologies Canada, Corp. Portions created by ICEsoft are Copyright (C)
17  * 2004-2006 ICEsoft Technologies Canada, Corp. All Rights Reserved.
18  *
19  * Contributor(s): _____________________.
20  *
21  * Alternatively, the contents of this file may be used under the terms of
22  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"
23  * License), in which case the provisions of the LGPL License are
24  * applicable instead of those above. If you wish to allow use of your
25  * version of this file only under the terms of the LGPL License and not to
26  * allow others to use your version of this file under the MPL, indicate
27  * your decision by deleting the provisions above and replace them with
28  * the notice and other provisions required by the LGPL License. If you do
29  * not delete the provisions above, a recipient may use your version of
30  * this file under either the MPL or the LGPL License."
31  *
32  */

33 /* Original Copyright
34  * Copyright 2004 The Apache Software Foundation.
35  *
36  * Licensed under the Apache License, Version 2.0 (the "License");
37  * you may not use this file except in compliance with the License.
38  * You may obtain a copy of the License at
39  *
40  * http://www.apache.org/licenses/LICENSE-2.0
41  *
42  * Unless required by applicable law or agreed to in writing, software
43  * distributed under the License is distributed on an "AS IS" BASIS,
44  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
45  * See the License for the specific language governing permissions and
46  * limitations under the License.
47  */

48 package com.icesoft.faces.component.selectinputdate;
49
50 import com.icesoft.faces.component.CSS_DEFAULT;
51 import com.icesoft.faces.component.ext.HtmlCommandLink;
52 import com.icesoft.faces.component.ext.HtmlGraphicImage;
53 import com.icesoft.faces.component.ext.HtmlOutputText;
54 import com.icesoft.faces.component.ext.renderkit.FormRenderer;
55 import com.icesoft.faces.component.util.CustomComponentUtils;
56 import com.icesoft.faces.context.DOMContext;
57 import com.icesoft.faces.renderkit.dom_html_basic.DomBasicInputRenderer;
58 import com.icesoft.faces.renderkit.dom_html_basic.HTML;
59 import com.icesoft.faces.renderkit.dom_html_basic.PassThruAttributeRenderer;
60 import com.icesoft.faces.util.CoreUtils;
61 import org.apache.commons.logging.Log;
62 import org.apache.commons.logging.LogFactory;
63 import org.w3c.dom.Element JavaDoc;
64 import org.w3c.dom.NodeList JavaDoc;
65 import org.w3c.dom.Text JavaDoc;
66
67 import javax.faces.component.NamingContainer;
68 import javax.faces.component.UIComponent;
69 import javax.faces.component.UIInput;
70 import javax.faces.component.UIParameter;
71 import javax.faces.component.UIViewRoot;
72 import javax.faces.context.FacesContext;
73 import javax.faces.context.ResponseWriter;
74 import javax.faces.convert.Converter;
75 import javax.faces.convert.ConverterException;
76 import java.io.IOException JavaDoc;
77 import java.text.DateFormat JavaDoc;
78 import java.text.DateFormatSymbols JavaDoc;
79 import java.text.ParseException JavaDoc;
80 import java.text.SimpleDateFormat JavaDoc;
81 import java.util.Calendar JavaDoc;
82 import java.util.Date JavaDoc;
83 import java.util.Locale JavaDoc;
84 import java.util.Map JavaDoc;
85 import java.util.regex.Matcher JavaDoc;
86 import java.util.regex.Pattern JavaDoc;
87
88 /**
89  * <p> The SelectInputDateRenderer class is an ICEfaces D2D renderer for the
90  * SelectInputDate component. Note: This class originally was derived from the
91  * MyFaces Calendar.</p>
92  */

93 public class SelectInputDateRenderer
94         extends DomBasicInputRenderer {
95     // add a static log member
96
private static final Log log =
97             LogFactory.getLog(SelectInputDateRenderer.class);
98
99     private final String JavaDoc CALENDAR_TABLE = "_calendarTable";
100     private final String JavaDoc CALENDAR_INPUTTEXT = "_calendarInputtext";
101     private final String JavaDoc CALENDAR_BUTTON = "_calendarButton";
102     private final String JavaDoc CALENDAR_POPUP = "_calendarPopup";
103     private final String JavaDoc HIDDEN_FIELD_NAME = "showPopup";
104     private final String JavaDoc DATE_SELECTED = "dateSelected";
105
106     // constants for navigation link ids
107
private final String JavaDoc PREV_MONTH = "_prevmo";
108     private final String JavaDoc NEXT_MONTH = "_nextmo";
109     private final String JavaDoc PREV_YEAR = "_prevyr";
110     private final String JavaDoc NEXT_YEAR = "_nextyr";
111
112     // constant for selectinputdate links
113
private final String JavaDoc CALENDAR = "_calendar";
114     
115     // arrays of week days and month names
116
String JavaDoc[] weekdays = new String JavaDoc[7];
117     String JavaDoc[] weekdaysLong = new String JavaDoc[7];
118     String JavaDoc[] months = new String JavaDoc[12];
119     
120     // store the current locale
121
Locale JavaDoc currentLocale = null;
122     
123
124     /* (non-Javadoc)
125     * @see javax.faces.render.Renderer#getRendersChildren()
126     */

127     public boolean getRendersChildren() {
128
129         return true;
130     }
131
132     /* (non-Javadoc)
133      * @see javax.faces.render.Renderer#encodeChildren(javax.faces.context.FacesContext, javax.faces.component.UIComponent)
134      */

135     public void encodeChildren(FacesContext facesContext,
136                                UIComponent uiComponent) {
137
138     }
139
140     private String JavaDoc getHiddenFieldName(FacesContext facesContext,
141                                       UIComponent uiComponent) {
142         UIComponent form = findForm(uiComponent);
143         String JavaDoc formId = form.getClientId(facesContext);
144         String JavaDoc clientId = uiComponent.getClientId(facesContext);
145         String JavaDoc hiddenFieldName = formId
146                                  + NamingContainer.SEPARATOR_CHAR
147                                  + UIViewRoot.UNIQUE_ID_PREFIX
148                                  + clientId
149                                  + HIDDEN_FIELD_NAME;
150         return hiddenFieldName;
151     }
152
153     /* (non-Javadoc)
154      * @see com.icesoft.faces.renderkit.dom_html_basic.DomBasicRenderer#encodeEnd(javax.faces.context.FacesContext, javax.faces.component.UIComponent)
155      */

156     public void encodeEnd(FacesContext facesContext, UIComponent uiComponent)
157             throws IOException JavaDoc {
158         validateParameters(facesContext, uiComponent, SelectInputDate.class);
159         DOMContext domContext =
160                 DOMContext.attachDOMContext(facesContext, uiComponent);
161         SelectInputDate selectInputDate = (SelectInputDate) uiComponent;
162
163         // get the parentForm
164
UIComponent parentForm = findForm(selectInputDate);
165         // if there is no parent form - ERROR
166
if (parentForm == null) {
167             log.error("SelectInputDate::must be in a FORM");
168             return;
169         }
170         String JavaDoc clientId;
171         if (!domContext.isInitialized()) {
172             Element JavaDoc root = domContext.createRootElement(HTML.DIV_ELEM);
173
174             setRootElementId(facesContext, root, uiComponent);
175             clientId = uiComponent.getClientId(facesContext);
176             if (selectInputDate.isRenderAsPopup()) {
177                 if (log.isTraceEnabled()) {
178                     log.trace("Render as popup");
179                 }
180                 Element JavaDoc dateText = domContext.createElement(HTML.INPUT_ELEM);
181                 dateText.setAttribute(HTML.VALUE_ATTR,
182                                       selectInputDate.formatDate(
183                                               (Date JavaDoc) selectInputDate
184                                                       .getValue()));
185                 dateText.setAttribute(HTML.ID_ATTR,
186                                       clientId + CALENDAR_INPUTTEXT);
187                 dateText.setAttribute(HTML.NAME_ATTR,
188                                       clientId + CALENDAR_INPUTTEXT);
189                 dateText.setAttribute(HTML.CLASS_ATTR,
190                                       selectInputDate.getCalendarInputClass());
191                 dateText.setAttribute(HTML.ONFOCUS_ATTR, "setFocus('');");
192                 dateText.setAttribute("onkeypress", this.ICESUBMIT);
193                 dateText.setAttribute(HTML.ONBLUR_ATTR, this.ICESUBMITPARTIAL);
194                 if (selectInputDate.getAutocomplete() != null) {
195                     dateText.setAttribute("autocomplete",
196                                           selectInputDate.getAutocomplete());
197                 }
198                 // extract the popupdate format and use it as a tooltip
199
String JavaDoc tooltip = selectInputDate.getPopupDateFormat();
200                 dateText.setAttribute(HTML.TITLE_ATTR,
201                                       "Date Format: " + tooltip);
202                 root.appendChild(dateText);
203                 Element JavaDoc calendarButton =
204                         domContext.createElement(HTML.INPUT_ELEM);
205                 calendarButton
206                         .setAttribute(HTML.ID_ATTR, clientId + CALENDAR_BUTTON);
207                 calendarButton.setAttribute(HTML.NAME_ATTR,
208                                             clientId + CALENDAR_BUTTON);
209                 calendarButton.setAttribute(HTML.TYPE_ATTR, "image");
210                 String JavaDoc resolvedSrc =
211                         CoreUtils.resolveResourceURL( facesContext,
212                                                       selectInputDate.getImageDir() +
213                                                       selectInputDate.getOpenPopupImage() );
214                 calendarButton.setAttribute(HTML.SRC_ATTR, resolvedSrc );
215                 calendarButton.setAttribute(HTML.ALT_ATTR, "Open Popup Calendar");
216                 calendarButton.setAttribute(HTML.TITLE_ATTR , "Open Popup Calendar");
217                 calendarButton.setAttribute(HTML.ONFOCUS_ATTR, "setFocus('');");
218                 // render onclick to set value of hidden field to true
219
String JavaDoc onClick = "document.forms['" +
220                                  parentForm.getClientId(facesContext) + "']['" +
221                                  this.getLinkId(facesContext, uiComponent) +
222                                  "'].value='" + clientId + CALENDAR_BUTTON +
223                                  "';"
224                                  + "document.forms['" +
225                                  parentForm.getClientId(facesContext) + "']['" +
226                                  getHiddenFieldName(facesContext, uiComponent) +
227                                  "'].value='toggle';"
228                                  + "iceSubmitPartial( document.forms['" +
229                                  parentForm.getClientId(facesContext) +
230                                  "'], this,event); return false;";
231                 calendarButton.setAttribute(HTML.ONCLICK_ATTR, onClick);
232                 root.appendChild(calendarButton);
233                 if (!domContext.isStreamWriting()) {
234                     Text br = domContext.createTextNode("<br/>");
235                     root.appendChild(br);
236                 }
237                 Element JavaDoc calendarDiv = domContext.createElement(HTML.DIV_ELEM);
238                 calendarDiv
239                         .setAttribute(HTML.ID_ATTR, clientId + CALENDAR_POPUP);
240                 calendarDiv.setAttribute(HTML.NAME_ATTR,
241                                          clientId + CALENDAR_POPUP);
242                 calendarDiv.setAttribute(HTML.STYLE_ELEM,
243                           "display:none;position:absolute;overflow:hidden;z-index:10;");
244                 calendarDiv.setAttribute(HTML.TITLE_ATTR, "A Popup Calendar where a date can be selected.");
245                 Element JavaDoc table = domContext.createElement(HTML.TABLE_ELEM);
246                 table.setAttribute(HTML.ID_ATTR, clientId + CALENDAR_TABLE);
247                 table.setAttribute(HTML.NAME_ATTR, clientId + CALENDAR_TABLE);
248                 table.setAttribute(HTML.CLASS_ATTR,
249                                    selectInputDate.getStyleClass());
250                 table.setAttribute(HTML.STYLE_ATTR, "position:absolute;");
251                 table.setAttribute(HTML.CELLPADDING_ATTR, "0");
252                 table.setAttribute(HTML.CELLSPACING_ATTR, "0");
253                 // set mouse events on table bug 372
254
String JavaDoc mouseOver = selectInputDate.getOnmouseover();
255                 table.setAttribute(HTML.ONMOUSEOVER_ATTR, mouseOver);
256                 String JavaDoc mouseOut = selectInputDate.getOnmouseout();
257                 table.setAttribute(HTML.ONMOUSEOUT_ATTR, mouseOut);
258                 String JavaDoc mouseMove = selectInputDate.getOnmousemove();
259                 table.setAttribute(HTML.ONMOUSEMOVE_ATTR, mouseMove);
260                 table.setAttribute(HTML.SUMMARY_ATTR,"This table contains a Calendar where a date can be selected.");
261                 calendarDiv.appendChild(table);
262                 Text iframe = domContext.createTextNode("<!--[if lte IE"+
263                         " 6.5]><iframe class=\"iceSelInpDateIFrameFix\"></iframe><![endif]-->");
264                 calendarDiv.appendChild(iframe);
265                 root.appendChild(calendarDiv);
266                 // render a hidden field to manage the popup state; visible || hidden
267
FormRenderer.addHiddenField(facesContext, getHiddenFieldName(
268                         facesContext, uiComponent));
269             } else {
270                 if (log.isTraceEnabled()) {
271                     log.trace("Select input Date Normal");
272                 }
273                 Element JavaDoc table = domContext.createElement(HTML.TABLE_ELEM);
274                 table.setAttribute(HTML.ID_ATTR, clientId + CALENDAR_TABLE);
275                 table.setAttribute(HTML.NAME_ATTR, clientId + CALENDAR_TABLE);
276                 table.setAttribute(HTML.CLASS_ATTR,
277                                    selectInputDate.getStyleClass());
278                 table.setAttribute(HTML.CELLPADDING_ATTR, "0");
279                 table.setAttribute(HTML.CELLSPACING_ATTR, "0");
280                 // set mouse events on table bug 372
281
String JavaDoc mouseOver = selectInputDate.getOnmouseover();
282                 table.setAttribute(HTML.ONMOUSEOVER_ATTR, mouseOver);
283                 String JavaDoc mouseOut = selectInputDate.getOnmouseout();
284                 table.setAttribute(HTML.ONMOUSEOUT_ATTR, mouseOut);
285                 String JavaDoc mouseMove = selectInputDate.getOnmousemove();
286                 table.setAttribute(HTML.ONMOUSEMOVE_ATTR, mouseMove);
287                 table.setAttribute(HTML.SUMMARY_ATTR,"This table contains a Calendar where a date can be selected.");
288                 root.appendChild(table);
289             }
290         }
291         clientId = uiComponent.getClientId(facesContext);
292         currentLocale = facesContext.getViewRoot().getLocale();
293
294         Date JavaDoc value;
295
296         if (selectInputDate.isNavEvent()) {
297             if (log.isTraceEnabled()) {
298                 log.trace("Rendering Nav Event");
299             }
300             value = selectInputDate.getNavDate();
301         } else {
302             if (log.isTraceEnabled()) {
303                 log.trace("Logging non nav event");
304             }
305             try {
306                 Converter converter = getConverter(selectInputDate);
307                 if (converter instanceof DateConverter) {
308                     value = ((DateConverter) converter)
309                             .getAsDate(facesContext, uiComponent);
310                 } else {
311                     value = CustomComponentUtils.getDateValue(selectInputDate);
312                 }
313             } catch (IllegalArgumentException JavaDoc illegalArgumentException) {
314                 value = null;
315             }
316         }
317
318         Calendar JavaDoc timeKeeper = Calendar.getInstance(currentLocale);
319         timeKeeper.setTime(value != null ? value : new Date JavaDoc());
320
321         DateFormatSymbols JavaDoc symbols = new DateFormatSymbols JavaDoc(currentLocale);
322
323         weekdays = mapWeekdays(symbols);
324         weekdaysLong = mapWeekdaysLong(symbols);
325         months = mapMonths(symbols);
326
327         // use the currentDay to set focus - do not set
328
int lastDayInMonth = timeKeeper.getActualMaximum(Calendar.DAY_OF_MONTH);
329         int currentDay = timeKeeper.get(Calendar.DAY_OF_MONTH); // starts at 1
330

331         if (currentDay > lastDayInMonth) {
332             currentDay = lastDayInMonth;
333         }
334
335         // get the current date value from the selectinputdate
336
Object JavaDoc currentValue = selectInputDate.getValue();
337
338         timeKeeper.set(Calendar.DAY_OF_MONTH, 1);
339
340         int weekDayOfFirstDayOfMonth =
341                 mapCalendarDayToCommonDay(timeKeeper.get(Calendar.DAY_OF_WEEK));
342
343         int weekStartsAtDayIndex =
344                 mapCalendarDayToCommonDay(timeKeeper.getFirstDayOfWeek());
345
346         // do not require a writer - clean out all methods that reference a writer
347
ResponseWriter writer = facesContext.getResponseWriter();
348
349         Element JavaDoc root = (Element JavaDoc) domContext.getRootNode();
350
351         if (selectInputDate.isRenderAsPopup()) {
352             if (log.isTraceEnabled()) {
353                 log.trace("SelectInputDate as Popup");
354             }
355
356             // assumption input text is first child
357
Element JavaDoc dateText = (Element JavaDoc) root.getFirstChild();
358
359             if (currentValue != null) {
360                     dateText.setAttribute(HTML.VALUE_ATTR,
361                                       selectInputDate.formatDate(
362                                               (Date JavaDoc) currentValue));
363             }
364
365             // assuming button is the second child
366
Element JavaDoc calendarButton =
367                     (Element JavaDoc) root.getFirstChild().getNextSibling();
368
369             // determine if the popup should be visible
370
// get selectinputdate div, assume it's the last child
371
Element JavaDoc calendarDiv = (Element JavaDoc) root.getLastChild();
372             boolean popupState = selectInputDate.isShowPopup();
373
374             if (popupState) {
375                 calendarDiv.setAttribute(HTML.STYLE_ELEM,
376                                          "z-index:10;display:block;position:absolute;");
377                 String JavaDoc resolvedSrc =
378                         CoreUtils.resolveResourceURL( facesContext,
379                                                       selectInputDate.getImageDir() +
380                                                       selectInputDate.getClosePopupImage() );
381                 calendarButton.setAttribute(HTML.SRC_ATTR, resolvedSrc );
382                 calendarButton.setAttribute(HTML.ALT_ATTR, "Close Popup Calendar");
383                 calendarButton.setAttribute(HTML.TITLE_ATTR , "Close Popup Calendar");
384             } else {
385                 calendarDiv.setAttribute(HTML.STYLE_ELEM,
386                                          "display:none;position:absolute;");
387                 String JavaDoc resolvedSrc =
388                         CoreUtils.resolveResourceURL( facesContext,
389                                                       selectInputDate.getImageDir() +
390                                                       selectInputDate.getOpenPopupImage() );
391                 calendarButton.setAttribute(HTML.SRC_ATTR, resolvedSrc );
392                 calendarButton.setAttribute(HTML.ALT_ATTR, "Open Popup Calendar");
393                 calendarButton.setAttribute(HTML.TITLE_ATTR , "Open Popup Calendar");
394             }
395
396             // get tables , our table is the first and only one
397
NodeList JavaDoc tables = root.getElementsByTagName(HTML.TABLE_ELEM);
398             // assumption we want the first table in tables. there should only be one
399
Element JavaDoc table = (Element JavaDoc) tables.item(0);
400
401             PassThruAttributeRenderer
402                     .renderAttributes(facesContext, uiComponent, null);
403
404             Element JavaDoc tr1 = domContext.createElement(HTML.TR_ELEM);
405
406             table.appendChild(tr1);
407
408             writeMonthYearHeader(domContext, facesContext, writer,
409                                  selectInputDate, timeKeeper,
410                                  currentDay, weekdays, months, tr1,
411                                  selectInputDate.getMonthYearRowClass());
412
413             Element JavaDoc tr2 = domContext.createElement(HTML.TR_ELEM);
414             table.appendChild(tr2);
415
416             writeWeekDayNameHeader(domContext, weekStartsAtDayIndex, weekdays,
417                                    facesContext, writer, selectInputDate, tr2,
418                                    selectInputDate.getWeekRowClass());
419
420             writeDays(domContext, facesContext, writer, selectInputDate,
421                       timeKeeper,
422                       currentDay, weekStartsAtDayIndex,
423                       weekDayOfFirstDayOfMonth,
424                       lastDayInMonth, weekdays, table);
425
426         } else {
427             if (log.isTraceEnabled()) {
428                 log.trace("renderNormal::endcodeEnd");
429             }
430             // assume table is the first child
431
Element JavaDoc table = (Element JavaDoc) root.getFirstChild();
432
433             PassThruAttributeRenderer
434                     .renderAttributes(facesContext, uiComponent, null);
435
436             Element JavaDoc tr1 = domContext.createElement(HTML.TR_ELEM);
437             table.appendChild(tr1);
438
439             writeMonthYearHeader(domContext, facesContext, writer,
440                                  selectInputDate, timeKeeper,
441                                  currentDay, weekdays, months, tr1,
442                                  selectInputDate.getMonthYearRowClass());
443
444             Element JavaDoc tr2 = domContext.createElement(HTML.TR_ELEM);
445
446             writeWeekDayNameHeader(domContext, weekStartsAtDayIndex, weekdays,
447                                    facesContext, writer, selectInputDate, tr2,
448                                    selectInputDate.getWeekRowClass());
449
450             table.appendChild(tr2);
451
452             writeDays(domContext, facesContext, writer, selectInputDate,
453                       timeKeeper,
454                       currentDay, weekStartsAtDayIndex,
455                       weekDayOfFirstDayOfMonth,
456                       lastDayInMonth, weekdays, table);
457
458         }
459
460         // purge child components as they have been encoded no need to keep them around
461
selectInputDate.getChildren().removeAll(selectInputDate.getChildren());
462
463         // steps to the position where the next sibling should be rendered
464
domContext.stepOver();
465         domContext.streamWrite(facesContext, uiComponent);
466     }
467
468     private void writeMonthYearHeader(DOMContext domContext,
469                                       FacesContext facesContext,
470                                       ResponseWriter writer,
471                                       SelectInputDate inputComponent,
472                                       Calendar JavaDoc timeKeeper,
473                                       int currentDay, String JavaDoc[] weekdays,
474                                       String JavaDoc[] months, Element JavaDoc headerTr,
475                                       String JavaDoc styleClass)
476             throws IOException JavaDoc {
477
478         Element JavaDoc table = domContext.createElement(HTML.TABLE_ELEM);
479         table.setAttribute(HTML.CELLPADDING_ATTR, "0");
480         table.setAttribute(HTML.CELLSPACING_ATTR, "0");
481         table.setAttribute(HTML.WIDTH_ATTR, "100%");
482         table.setAttribute(HTML.SUMMARY_ATTR,"Month Year navigation header");
483
484         Element JavaDoc tr = domContext.createElement(HTML.TR_ELEM);
485
486         Element JavaDoc headertd = domContext.createElement(HTML.TD_ELEM);
487         table.appendChild(tr);
488         headertd.appendChild(table);
489         headerTr.appendChild(headertd);
490
491         headertd.setAttribute(HTML.COLSPAN_ATTR, "7"); // weekdays.length = 7
492

493         // first render month with navigation back and forward
494
Calendar JavaDoc cal = shiftMonth(facesContext, timeKeeper, currentDay, -1);
495         writeCell(domContext, facesContext, writer, inputComponent,
496                   "<", cal.getTime(), styleClass, tr,
497                   ((SelectInputDate) inputComponent).getImageDir() +
498                   ((SelectInputDate) inputComponent).getMovePreviousImage(), -1);
499
500         Element JavaDoc td = domContext.createElement(HTML.TD_ELEM);
501         td.setAttribute(HTML.CLASS_ATTR, styleClass);
502         td.setAttribute(HTML.WIDTH_ATTR, "40%");
503         Text text = domContext
504                 .createTextNode(months[timeKeeper.get(Calendar.MONTH)] + "");
505         td.appendChild(text);
506
507         tr.appendChild(td);
508
509         cal = shiftMonth(facesContext, timeKeeper, currentDay, 1);
510         int calYear = cal.get(Calendar.YEAR);
511
512         if (inputComponent.getHightlightRules().containsKey(Calendar.YEAR+"$"+calYear)) {
513             inputComponent.setHighlightYearClass(inputComponent.getHightlightRules().get(Calendar.YEAR+"$"+calYear) + " ");
514         } else {
515             inputComponent.setHighlightYearClass("");
516         }
517               
518         int calMonth = cal.get(Calendar.MONTH);
519         if (inputComponent.getHightlightRules().containsKey(Calendar.MONTH+"$"+calMonth)) {
520             inputComponent.setHighlightMonthClass(inputComponent.getHightlightRules().get(Calendar.MONTH+"$"+calMonth) + " ");
521         } else {
522             inputComponent.setHighlightMonthClass("");
523         }
524         writeCell(domContext, facesContext, writer, inputComponent,
525                   ">", cal.getTime(), styleClass, tr,
526                   ((SelectInputDate) inputComponent).getImageDir() +
527                   ((SelectInputDate) inputComponent).getMoveNextImage(), -1);
528
529         // second add an empty td
530
Element JavaDoc emptytd = domContext.createElement(HTML.TD_ELEM);
531         emptytd.setAttribute(HTML.CLASS_ATTR, styleClass);
532         Text emptytext = domContext.createTextNode("");
533         emptytd.appendChild(emptytext);
534
535         tr.appendChild(emptytd);
536
537         // third render year with navigation back and forward
538
cal = shiftYear(facesContext, timeKeeper, currentDay, -1);
539
540         writeCell(domContext, facesContext, writer, inputComponent,
541                   "<<", cal.getTime(), styleClass, tr,
542                   ((SelectInputDate) inputComponent).getImageDir() +
543                   ((SelectInputDate) inputComponent).getMovePreviousImage(), -1);
544
545         Element JavaDoc yeartd = domContext.createElement(HTML.TD_ELEM);
546         yeartd.setAttribute(HTML.CLASS_ATTR, styleClass);
547         Text yeartext =
548                 domContext.createTextNode("" + timeKeeper.get(Calendar.YEAR));
549         yeartd.appendChild(yeartext);
550
551         tr.appendChild(yeartd);
552
553         cal = shiftYear(facesContext, timeKeeper, currentDay, 1);
554
555         writeCell(domContext, facesContext, writer, inputComponent,
556                   ">>", cal.getTime(), styleClass, tr,
557                   ((SelectInputDate) inputComponent).getImageDir() +
558                   ((SelectInputDate) inputComponent).getMoveNextImage(), -1);
559
560     }
561
562     private Calendar JavaDoc shiftMonth(FacesContext facesContext,
563                                 Calendar JavaDoc timeKeeper, int currentDay,
564                                 int shift) {
565         Calendar JavaDoc cal = copyCalendar(facesContext, timeKeeper);
566
567         cal.set(Calendar.MONTH, cal.get(Calendar.MONTH) + shift);
568
569         if (currentDay > cal.getActualMaximum(Calendar.DAY_OF_MONTH)) {
570             currentDay = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
571         }
572
573         cal.set(Calendar.DAY_OF_MONTH, currentDay);
574         return cal;
575     }
576
577     private Calendar JavaDoc shiftYear(FacesContext facesContext,
578                                Calendar JavaDoc timeKeeper, int currentDay, int shift) {
579         Calendar JavaDoc cal = copyCalendar(facesContext, timeKeeper);
580         
581         cal.set(Calendar.YEAR, cal.get(Calendar.YEAR) + shift);
582
583         if (currentDay > cal.getActualMaximum(Calendar.DAY_OF_MONTH)) {
584             currentDay = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
585         }
586
587         cal.set(Calendar.DAY_OF_MONTH, currentDay);
588         return cal;
589     }
590
591     private Calendar JavaDoc copyCalendar(FacesContext facesContext,
592                                   Calendar JavaDoc timeKeeper) {
593         Calendar JavaDoc cal =
594                 Calendar.getInstance(facesContext.getViewRoot().getLocale());
595         cal = (Calendar JavaDoc) timeKeeper.clone();
596         return cal;
597     }
598
599     private void writeWeekDayNameHeader(DOMContext domContext,
600                                         int weekStartsAtDayIndex,
601                                         String JavaDoc[] weekdays,
602                                         FacesContext facesContext,
603                                         ResponseWriter writer,
604                                         UIInput inputComponent, Element JavaDoc tr,
605                                         String JavaDoc styleClass)
606             throws IOException JavaDoc {
607         // the week can start with Sunday (index 0) or Monday (index 1)
608
for (int i = weekStartsAtDayIndex; i < weekdays.length; i++) {
609             writeCell(domContext, facesContext,
610                       writer, inputComponent, weekdays[i], null, styleClass, tr,
611                       null, i);
612         }
613
614         // if week start on Sunday this block is not executed
615
// if week start on Monday this block will run once adding Sunday to End of week.
616
for (int i = 0; i < weekStartsAtDayIndex; i++) {
617             writeCell(domContext, facesContext, writer,
618                       inputComponent, weekdays[i], null, styleClass, tr, null, i);
619         }
620     }
621
622     private void writeDays(DOMContext domContext, FacesContext facesContext,
623                            ResponseWriter writer,
624                            SelectInputDate inputComponent, Calendar JavaDoc timeKeeper,
625                            int currentDay, int weekStartsAtDayIndex,
626                            int weekDayOfFirstDayOfMonth, int lastDayInMonth,
627                            String JavaDoc[] weekdays, Element JavaDoc table)
628             throws IOException JavaDoc {
629         Calendar JavaDoc cal;
630
631         int space = (weekStartsAtDayIndex < weekDayOfFirstDayOfMonth) ?
632                     (weekDayOfFirstDayOfMonth - weekStartsAtDayIndex)
633                     : (weekdays.length - weekStartsAtDayIndex +
634                        weekDayOfFirstDayOfMonth);
635
636         if (space == weekdays.length) {
637             space = 0;
638         }
639
640         int columnIndexCounter = 0;
641
642         Element JavaDoc tr1 = null;
643         for (int i = 0; i < space; i++) {
644             if (columnIndexCounter == 0) {
645                 tr1 = domContext.createElement(HTML.TR_ELEM);
646                 table.appendChild(tr1);
647             }
648
649             writeCell(domContext, facesContext, writer, inputComponent, "",
650                       null, inputComponent.getDayCellClass(), tr1, null, i);
651             columnIndexCounter++;
652         }
653
654         Element JavaDoc tr2 = null;
655         for (int i = 0; i < lastDayInMonth; i++) {
656             if (columnIndexCounter == 0) {
657                 // don't create a new row until we have finished the last
658
tr2 = domContext.createElement(HTML.TR_ELEM);
659                 table.appendChild(tr2);
660             }
661
662             cal = copyCalendar(facesContext, timeKeeper);
663             cal.set(Calendar.DAY_OF_MONTH,
664                     i + 1); // i starts at 0 DAY_OF_MONTH start at 1
665

666             // get day, month and year
667
// use these to check if the currentDayCell style class should be used
668
int day = 0;
669             int month = 0;
670             int year = 0;
671             try {
672                 Date JavaDoc currentDate = (Date JavaDoc) inputComponent.getValue();
673                 Calendar JavaDoc current = Calendar.getInstance();
674                 current.setTime(currentDate);
675                 
676                 day = current.get(Calendar.DAY_OF_MONTH); // starts with 1
677
month = current.get(Calendar.MONTH); // starts with 0
678
year = current.get(Calendar.YEAR);
679             } catch (Exception JavaDoc e) {
680                 // hmmm this should never happen
681
}
682             
683            
684             if (inputComponent.getHightlightRules().size()>0) {
685                 int weekOfYear = cal.get(Calendar.WEEK_OF_YEAR);
686                 int weekOfMonth = cal.get(Calendar.WEEK_OF_MONTH);
687                 int date =cal.get(Calendar.DATE);
688                 int dayOfYear = cal.get(Calendar.DAY_OF_YEAR);
689                 int dayOfWeek = cal.get(Calendar.DAY_OF_WEEK);
690                 int dayOfWeekInMonth = cal.get(Calendar.DAY_OF_WEEK_IN_MONTH);
691                 
692                 if (inputComponent.getHightlightRules().containsKey(Calendar.WEEK_OF_YEAR+"$"+weekOfYear)) {
693                     inputComponent.addHighlightWeekClass(String.valueOf(inputComponent.getHightlightRules().get(Calendar.WEEK_OF_YEAR+"$"+weekOfYear)));
694                 }
695                 if (inputComponent.getHightlightRules().containsKey(Calendar.WEEK_OF_MONTH+"$"+weekOfMonth)) {
696                     inputComponent.addHighlightWeekClass(String.valueOf(inputComponent.getHightlightRules().get(Calendar.WEEK_OF_MONTH+"$"+weekOfMonth)));
697                 }
698                 if (inputComponent.getHightlightRules().containsKey(Calendar.DATE+"$"+date)) {
699                     inputComponent.addHighlightDayClass(String.valueOf(inputComponent.getHightlightRules().get(Calendar.DATE+"$"+date)));
700                 }
701                 if (inputComponent.getHightlightRules().containsKey(Calendar.DAY_OF_YEAR+"$"+dayOfYear)) {
702                     inputComponent.addHighlightDayClass(String.valueOf(inputComponent.getHightlightRules().get(Calendar.DAY_OF_YEAR+"$"+dayOfYear)));
703                 }
704                 if (inputComponent.getHightlightRules().containsKey(Calendar.DAY_OF_WEEK+"$"+dayOfWeek)) {
705                     inputComponent.addHighlightDayClass(String.valueOf(inputComponent.getHightlightRules().get(Calendar.DAY_OF_WEEK+"$"+dayOfWeek)));
706                 }
707                 if (inputComponent.getHightlightRules().containsKey(Calendar.DAY_OF_WEEK_IN_MONTH+"$"+dayOfWeekInMonth)) {
708                     inputComponent.addHighlightDayClass(String.valueOf(inputComponent.getHightlightRules().get(Calendar.DAY_OF_WEEK_IN_MONTH+"$"+dayOfWeekInMonth)));
709                 }
710             }
711             
712             String JavaDoc cellStyle = inputComponent.getHighlightDayCellClass() + inputComponent.getDayCellClass();
713             
714             
715             if ((cal.get(Calendar.DAY_OF_MONTH) == day) &&
716                     (cal.get(Calendar.MONTH) == month) &&
717                     (cal.get(Calendar.YEAR) == year)) {
718                     cellStyle = inputComponent.getCurrentDayCellClass();
719                 }
720              
721             
722             // do not automatically select date when navigating by month
723
if ((cal.get(Calendar.DAY_OF_MONTH) == day) &&
724                 (cal.get(Calendar.MONTH) == month) &&
725                 (cal.get(Calendar.YEAR) == year)) {
726                 cellStyle = inputComponent.getCurrentDayCellClass();
727             }
728
729             if (tr2 == null) {
730                 // finish the first row
731
writeCell(domContext, facesContext, writer,
732                           inputComponent, String.valueOf(i + 1), cal.getTime(),
733                           cellStyle, tr1, null, i);
734             } else {
735                 // write to new row
736
writeCell(domContext, facesContext, writer,
737                           inputComponent, String.valueOf(i + 1), cal.getTime(),
738                           cellStyle, tr2, null, i);
739             }
740
741             columnIndexCounter++;
742
743             if (columnIndexCounter == weekdays.length) {
744                 columnIndexCounter = 0;
745             }
746             inputComponent.resetHighlightClasses(Calendar.WEEK_OF_YEAR);
747         }
748
749         if ((columnIndexCounter != 0) && (tr2 != null)) {
750             for (int i = columnIndexCounter; i < weekdays.length; i++) {
751                 writeCell(domContext, facesContext, writer,
752                           inputComponent, "", null,
753                           inputComponent.getDayCellClass(), tr2, null, i);
754              }
755         }
756
757     }
758
759     private void writeCell(DOMContext domContext, FacesContext facesContext,
760                            ResponseWriter writer, UIInput component,
761                            String JavaDoc content,
762                            Date JavaDoc valueForLink, String JavaDoc styleClass, Element JavaDoc tr,
763                            String JavaDoc imgSrc, int weekDayIndex)
764             throws IOException JavaDoc {
765         Element JavaDoc td = domContext.createElement(HTML.TD_ELEM);
766         tr.appendChild(td);
767
768         if (styleClass != null) {
769             td.setAttribute(HTML.CLASS_ATTR, styleClass);
770         }
771
772         if (valueForLink == null) {
773             Text text = domContext.createTextNode(content);
774             td.setAttribute(HTML.TITLE_ATTR,weekdaysLong[weekDayIndex]);
775             td.appendChild(text);
776         } else {
777             // set cursor to render into the td
778
domContext.setCursorParent(td);
779             domContext.streamWrite(facesContext, component,
780                                    domContext.getRootNode(), td);
781             writeLink(content, component, facesContext, valueForLink,
782                       styleClass, imgSrc, td);
783             // steps to the position where the next sibling should be rendered
784
domContext.stepOver();
785         }
786
787     }
788
789     private void writeLink(String JavaDoc content,
790                            UIInput component,
791                            FacesContext facesContext,
792                            Date JavaDoc valueForLink,
793                            String JavaDoc styleClass,
794                            String JavaDoc imgSrc,
795                            Element JavaDoc td)
796             throws IOException JavaDoc {
797
798         Converter converter = getConverter(component);
799         HtmlCommandLink link = new HtmlCommandLink();
800         Calendar JavaDoc cal = Calendar.getInstance(currentLocale);
801         cal.setTime(valueForLink);
802         String JavaDoc month = months[cal.get(Calendar.MONTH)];
803         String JavaDoc year = String.valueOf(cal.get(Calendar.YEAR));
804         int dayInt = cal.get(Calendar.DAY_OF_WEEK);
805         dayInt = mapCalendarDayToCommonDay(dayInt);
806         String JavaDoc day = weekdaysLong[dayInt];
807         String JavaDoc altText = "";
808         // assign special ids for navigation links
809
if (content.equals("<")) {
810             link.setId(component.getId() + this.PREV_MONTH);
811             altText = "Move to previous month " + month;
812         } else if (content.equals(">")) {
813             link.setId(component.getId() + this.NEXT_MONTH);
814             altText = "Move to next month " + month;
815         } else if (content.equals(">>")) {
816             link.setId(component.getId() + this.NEXT_YEAR);
817             altText = "Move to next year " + year;
818         } else if (content.equals("<<")) {
819             link.setId(component.getId() + this.PREV_YEAR);
820             altText = "Move to previous year " + year;
821         } else {
822             link.setId(component.getId() + "_" + content.hashCode() + this
823                     .CALENDAR);
824             if (log.isDebugEnabled()) {
825                 log.debug("linkId=" + component.getId() + "_" +
826                           content.hashCode() + this.CALENDAR);
827             }
828         }
829
830         link.setPartialSubmit(true);
831         link.setTransient(true);
832         link.setImmediate(component.isImmediate());
833
834         if (imgSrc != null) {
835             HtmlGraphicImage img = new HtmlGraphicImage();
836             img.setUrl(imgSrc);
837             img.setHeight("16");
838             img.setWidth("17");
839             img.setStyle("border:none;");
840             img.setAlt(altText);
841             img.setId(component.getId() + "_" + content.hashCode() + "_img");
842             img.setTransient(true);
843             link.getChildren().add(img);
844         } else {
845             HtmlOutputText text = new HtmlOutputText();
846             text.setValue(content);
847             text.setId(component.getId() + "_" + content.hashCode() + "_text");
848             text.setTransient(true);
849             text.setTitle(day);
850             link.getChildren().add(text);
851         }
852         // links are focus aware
853
UIParameter parameter = new UIParameter();
854         parameter.setId(
855                 component.getId() + "_" + valueForLink.getTime() + "_param");
856         parameter.setTransient(true);
857         parameter.setName(component.getClientId(facesContext));
858         parameter.setValue(
859                 converter.getAsString(facesContext, component, valueForLink));
860
861         component.getChildren().add(link);
862         link.getChildren().add(parameter);
863
864         //don't add this parameter for next and previouse button/link
865
if (!content.equals("<") && !content.equals(">") &&
866             !content.equals(">>") && !content.equals("<<")) {
867             //this parameter would be use to close the popup selectinputdate after date selection.
868
parameter = new UIParameter();
869             parameter.setId(component.getId() + "_" + valueForLink.getTime() +
870                             "_" + DATE_SELECTED);
871             parameter.setName(getHiddenFieldName(facesContext, component));
872             parameter.setValue("false");
873             link.getChildren().add(parameter);
874         }
875         link.encodeBegin(facesContext);
876         link.encodeChildren(facesContext);
877         link.encodeEnd(facesContext);
878         td.setAttribute(HTML.ID_ATTR, link.getClientId(facesContext) + "td");
879         try {
880             Integer.parseInt(content);
881             ((SelectInputDate) component).getLinkMap()
882                     .put(link.getClientId(facesContext), td);
883             if (styleClass.equals(CSS_DEFAULT.DEFAULT_CALENDAR + CSS_DEFAULT
884                     .DEFAULT_CURRENTDAYCELL_CLASS)) {
885                 ((SelectInputDate) component)
886                         .setSelectedDayLink(link.getClientId(facesContext));
887             }
888         } catch (NumberFormatException JavaDoc e) {
889
890         }
891
892
893     }
894
895     private Converter getConverter(UIInput component) {
896         Converter converter = component.getConverter();
897
898         if (converter == null) {
899             converter = new CalendarDateTimeConverter();
900         }
901         return converter;
902     }
903
904     private int mapCalendarDayToCommonDay(int day) {
905         switch (day) {
906             case Calendar.TUESDAY:
907                 return 1;
908             case Calendar.WEDNESDAY:
909                 return 2;
910             case Calendar.THURSDAY:
911                 return 3;
912             case Calendar.FRIDAY:
913                 return 4;
914             case Calendar.SATURDAY:
915                 return 5;
916             case Calendar.SUNDAY:
917                 return 6;
918             default:
919                 return 0;
920         }
921     }
922
923     private static String JavaDoc[] mapWeekdays(DateFormatSymbols JavaDoc symbols) {
924         String JavaDoc[] weekdays = new String JavaDoc[7];
925
926         String JavaDoc[] localeWeekdays = symbols.getShortWeekdays();
927
928         weekdays[0] = localeWeekdays[Calendar.MONDAY];
929         weekdays[1] = localeWeekdays[Calendar.TUESDAY];
930         weekdays[2] = localeWeekdays[Calendar.WEDNESDAY];
931         weekdays[3] = localeWeekdays[Calendar.THURSDAY];
932         weekdays[4] = localeWeekdays[Calendar.FRIDAY];
933         weekdays[5] = localeWeekdays[Calendar.SATURDAY];
934         weekdays[6] = localeWeekdays[Calendar.SUNDAY];
935
936         return weekdays;
937     }
938
939     private static String JavaDoc[] mapWeekdaysLong(DateFormatSymbols JavaDoc symbols) {
940         String JavaDoc[] weekdays = new String JavaDoc[7];
941
942         String JavaDoc[] localeWeekdays = symbols.getWeekdays();
943
944         weekdays[0] = localeWeekdays[Calendar.MONDAY];
945         weekdays[1] = localeWeekdays[Calendar.TUESDAY];
946         weekdays[2] = localeWeekdays[Calendar.WEDNESDAY];
947         weekdays[3] = localeWeekdays[Calendar.THURSDAY];
948         weekdays[4] = localeWeekdays[Calendar.FRIDAY];
949         weekdays[5] = localeWeekdays[Calendar.SATURDAY];
950         weekdays[6] = localeWeekdays[Calendar.SUNDAY];
951
952         return weekdays;
953     }
954
955     /**
956      * @param symbols
957      * @return months - String[] containing localized month names
958      */

959     public static String JavaDoc[] mapMonths(DateFormatSymbols JavaDoc symbols) {
960         String JavaDoc[] months = new String JavaDoc[12];
961
962         String JavaDoc[] localeMonths = symbols.getMonths();
963
964         months[0] = localeMonths[Calendar.JANUARY];
965         months[1] = localeMonths[Calendar.FEBRUARY];
966         months[2] = localeMonths[Calendar.MARCH];
967         months[3] = localeMonths[Calendar.APRIL];
968         months[4] = localeMonths[Calendar.MAY];
969         months[5] = localeMonths[Calendar.JUNE];
970         months[6] = localeMonths[Calendar.JULY];
971         months[7] = localeMonths[Calendar.AUGUST];
972         months[8] = localeMonths[Calendar.SEPTEMBER];
973         months[9] = localeMonths[Calendar.OCTOBER];
974         months[10] = localeMonths[Calendar.NOVEMBER];
975         months[11] = localeMonths[Calendar.DECEMBER];
976
977         return months;
978     }
979
980     /**
981      * @param facesContext
982      * @param uiComponent
983      * @return id - used for the commandlink hidden field in the form
984      */

985     public String JavaDoc getLinkId(FacesContext facesContext,
986                             UIComponent uiComponent) {
987         //this is a fix for bug 340
988
UIComponent form = findForm(uiComponent);
989         String JavaDoc formId = form.getClientId(facesContext);
990         return formId + ":_idcl";
991     }
992
993     private boolean checkLink(String JavaDoc clickedLink, String JavaDoc clientId) {
994         if (clickedLink == null) {
995             return false;
996         }
997         boolean found = false;
998         String JavaDoc REGEX = clientId;
999         String JavaDoc INPUT = clickedLink;
1000        Pattern JavaDoc pattern;
1001        Matcher JavaDoc matcher;
1002
1003        pattern = Pattern.compile(REGEX);
1004        matcher = pattern.matcher(INPUT);
1005
1006        while (matcher.find()) {
1007            found = true;
1008        }
1009
1010        return found;
1011    }
1012
1013    /* (non-Javadoc)
1014    * @see com.icesoft.faces.renderkit.dom_html_basic.DomBasicRenderer#decode(javax.faces.context.FacesContext, javax.faces.component.UIComponent)
1015    */

1016    public void decode(FacesContext facesContext, UIComponent component) {
1017        validateParameters(facesContext, component, SelectInputDate.class);
1018        Map JavaDoc requestParameterMap =
1019                facesContext.getExternalContext().getRequestParameterMap();
1020        Object JavaDoc linkId = getLinkId(facesContext, component);
1021        Object JavaDoc clickedLink = requestParameterMap.get(linkId);
1022        String JavaDoc clientId = component.getClientId(facesContext);
1023
1024        Map JavaDoc parameter =
1025                facesContext.getExternalContext().getRequestParameterMap();
1026        String JavaDoc param =
1027                (String JavaDoc) parameter.get(component.getClientId(facesContext));
1028        if (param != null) {
1029
1030
1031            if (log.isDebugEnabled()) {
1032                log.debug("linkId::" + linkId + " clickedLink::" +
1033                          clickedLink + " clientId::" + clientId);
1034            }
1035
1036            if (checkLink((String JavaDoc) clickedLink, clientId)) {
1037                if (log.isDebugEnabled()) {
1038                    log.debug("---------------------------------");
1039                    log.debug("----------START::DECODE----------");
1040                    log.debug("---------------------------------");
1041                    log.debug("decode::linkId::" + linkId + "=" + clickedLink +
1042                              " clientId::" + clientId);
1043                }
1044
1045                if (((String JavaDoc) clickedLink).endsWith(this.PREV_MONTH) ||
1046                    ((String JavaDoc) clickedLink).endsWith(this.NEXT_MONTH) ||
1047                    ((String JavaDoc) clickedLink).endsWith(this.PREV_YEAR) ||
1048                    ((String JavaDoc) clickedLink).endsWith(this.NEXT_YEAR)) {
1049                    if (log.isDebugEnabled()) {
1050                        log.debug("-------------Navigation Event-------------");
1051                    }
1052                    decodeNavigation(facesContext, component);
1053                } else if (((String JavaDoc) clickedLink).endsWith(this.CALENDAR)) {
1054                    if (log.isDebugEnabled()) {
1055                        log.debug(
1056                                "-------------Select Date Event-------------");
1057                    }
1058                    decodeSelectDate(facesContext, component);
1059                } else
1060                if (((String JavaDoc) clickedLink).endsWith(this.CALENDAR_BUTTON)) {
1061                    if (log.isDebugEnabled()) {
1062                        log.debug(
1063                                "-------------Popup Event-------------------");
1064                    }
1065                    decodePopup(facesContext, component);
1066                }
1067            } else {
1068                if (log.isDebugEnabled()) {
1069                    log.debug("-------------InputText enterkey Event ??----");
1070                }
1071                decodeInputText(facesContext, component);
1072            }
1073
1074        }
1075    }
1076
1077    private void decodeNavigation(FacesContext facesContext,
1078                                  UIComponent component) {
1079        Map JavaDoc requestParameterMap =
1080                facesContext.getExternalContext().getRequestParameterMap();
1081        SelectInputDate dateSelect = (SelectInputDate) component;
1082
1083        // set the navDate on the Calendar
1084
if (log.isDebugEnabled()) {
1085            log.debug("setNavDate::");
1086            log.debug("#################################");
1087        }
1088        dateSelect.setNavEvent(true);
1089        dateSelect.setNavDate((Date JavaDoc) getConvertedValue(facesContext, dateSelect,
1090                                                       requestParameterMap.get(
1091                                                               dateSelect.getClientId(
1092                                                                       facesContext))));
1093    }
1094
1095    private void decodePopup(FacesContext facesContext, UIComponent component) {
1096        Map JavaDoc requestParameterMap =
1097                facesContext.getExternalContext().getRequestParameterMap();
1098        String JavaDoc popupState = getHiddenFieldName(facesContext, component);
1099        String JavaDoc showPopup = (String JavaDoc) requestParameterMap.get(popupState);
1100        SelectInputDate dateSelect = (SelectInputDate) component;
1101
1102        if (log.isDebugEnabled()) {
1103            log.debug("decodePopup::" + showPopup);
1104            log.debug("#################################");
1105        }
1106        // check showPopup
1107
if (showPopup != null) {
1108
1109            dateSelect.setShowPopup(!dateSelect.isShowPopup());
1110        }
1111        // not a nav event
1112
dateSelect.setNavEvent(false);
1113    }
1114
1115    private void decodeSelectDate(FacesContext facesContext,
1116                                  UIComponent component) {
1117
1118        Map JavaDoc requestParameterMap =
1119                facesContext.getExternalContext().getRequestParameterMap();
1120        String JavaDoc popupState = getHiddenFieldName(facesContext, component);
1121        String JavaDoc showPopup = (String JavaDoc) requestParameterMap.get(popupState);
1122        SelectInputDate dateSelect = (SelectInputDate) component;
1123
1124        if (log.isDebugEnabled()) {
1125            log.debug("selectDate::showPopup" + showPopup);
1126            log.debug("#################################");
1127        }
1128        if (showPopup != null) {
1129            if (showPopup.equalsIgnoreCase("true")) {
1130                dateSelect.setShowPopup(true);
1131            } else {
1132                dateSelect.setShowPopup(false);
1133            }
1134        }
1135        if (log.isDebugEnabled()) {
1136            log.debug("decodeUIInput::");
1137            log.debug("#################################");
1138        }
1139        CustomComponentUtils.decodeUIInput(facesContext, component);
1140        // not a navigation event
1141
dateSelect.setNavEvent(false);
1142    }
1143
1144    private void decodeInputText(FacesContext facesContext,
1145                                 UIComponent component) {
1146        Map JavaDoc requestParameterMap =
1147                facesContext.getExternalContext().getRequestParameterMap();
1148        String JavaDoc popupState = getHiddenFieldName(facesContext, component);
1149        String JavaDoc showPopup = (String JavaDoc) requestParameterMap.get(popupState);
1150        SelectInputDate dateSelect = (SelectInputDate) component;
1151        String JavaDoc clientId = dateSelect.getClientId(facesContext);
1152        Object JavaDoc linkId = getLinkId(facesContext, component);
1153        Object JavaDoc clickedLink = requestParameterMap.get(linkId);
1154
1155        // inputtext is only available in popup mode
1156
if ((requestParameterMap.containsKey(clientId)) &&
1157            dateSelect.isRenderAsPopup()) {
1158            if (log.isDebugEnabled()) {
1159                log.debug("decoding InputText EnterKey::");
1160                log.debug("###################################");
1161            }
1162            if (showPopup != null) {
1163                String JavaDoc inputTextDateId = component.getClientId(facesContext) +
1164                                         CALENDAR_INPUTTEXT;
1165                Object JavaDoc inputTextDate = requestParameterMap.get(inputTextDateId);
1166                
1167                if (checkLink((String JavaDoc) clickedLink, clientId)) {
1168                    if (showPopup.equalsIgnoreCase("true")) {
1169                        dateSelect.setShowPopup(true);
1170                    } else {
1171                        dateSelect.setShowPopup(false);
1172                    }
1173                }
1174                if (String.valueOf(inputTextDate).equals("")) {
1175                    dateSelect.setSubmittedValue("null");
1176                } else {
1177                    dateSelect.setSubmittedValue(inputTextDate);
1178                }
1179            }
1180        }
1181    }
1182
1183    /* (non-Javadoc)
1184     * @see com.icesoft.faces.renderkit.dom_html_basic.DomBasicInputRenderer#getConvertedValue(javax.faces.context.FacesContext, javax.faces.component.UIComponent, java.lang.Object)
1185     */

1186    public Object JavaDoc getConvertedValue(FacesContext facesContext,
1187                                    UIComponent uiComponent,
1188                                    Object JavaDoc submittedValue)
1189            throws ConverterException {
1190        validateParameters(facesContext, uiComponent, SelectInputDate.class);
1191        Converter converter;
1192
1193        converter = new CalendarDateTimeConverter();
1194
1195        if (!(submittedValue == null || submittedValue instanceof String JavaDoc)) {
1196            throw new IllegalArgumentException JavaDoc(
1197                    "Submitted value of type String expected");
1198        }
1199        Object JavaDoc o = converter.getAsObject(facesContext, uiComponent,
1200                (String JavaDoc) submittedValue);
1201        
1202        return o;
1203    }
1204
1205    /**
1206     *
1207     */

1208    public interface DateConverter extends Converter {
1209        public Date JavaDoc getAsDate(FacesContext facesContext,
1210                              UIComponent uiComponent);
1211    }
1212
1213    /**
1214     *
1215     */

1216    public static class CalendarDateTimeConverter implements Converter {
1217
1218        /* (non-Javadoc)
1219         * @see javax.faces.convert.Converter#getAsObject(javax.faces.context.FacesContext, javax.faces.component.UIComponent, java.lang.String)
1220         */

1221        public Object JavaDoc getAsObject(FacesContext facesContext,
1222                                  UIComponent uiComponent, String JavaDoc s) {
1223            
1224            if (s == null || s.trim().length() == 0) {
1225                return null;
1226            } else if ("null".equals(s)){
1227                return null;
1228            }
1229
1230            DateFormat JavaDoc dateFormat = null;
1231
1232            if (uiComponent instanceof SelectInputDate &&
1233                ((SelectInputDate) uiComponent).isRenderAsPopup()) {
1234                String JavaDoc popupDateFormat =
1235                        ((SelectInputDate) uiComponent).getPopupDateFormat();
1236                dateFormat = new SimpleDateFormat JavaDoc(popupDateFormat);
1237            } else {
1238                dateFormat = createStandardDateFormat(facesContext);
1239            }
1240
1241            try {
1242                return dateFormat.parse(s);
1243            }
1244            catch (ParseException JavaDoc e) {
1245                ConverterException ex = new ConverterException(e);
1246                throw ex;
1247            }
1248        }
1249
1250        /**
1251         * @param facesContext
1252         * @param popupDateFormat
1253         * @return jsPopupDateFormat
1254         */

1255        public static String JavaDoc createJSPopupFormat(FacesContext facesContext,
1256                                                 String JavaDoc popupDateFormat) {
1257
1258            if (popupDateFormat == null) {
1259                SimpleDateFormat JavaDoc defaultDateFormat =
1260                        createStandardDateFormat(facesContext);
1261                popupDateFormat = defaultDateFormat.toPattern();
1262            }
1263
1264            StringBuffer JavaDoc jsPopupDateFormat = new StringBuffer JavaDoc();
1265
1266            for (int i = 0; i < popupDateFormat.length(); i++) {
1267                char c = popupDateFormat.charAt(i);
1268
1269                if (c == 'M') {
1270                    jsPopupDateFormat.append('M');
1271                } else if (c == 'd') {
1272                    jsPopupDateFormat.append('d');
1273                } else if (c == 'y') {
1274                    jsPopupDateFormat.append('y');
1275                } else if (c == ' ') {
1276                    jsPopupDateFormat.append(' ');
1277                } else if (c == '.') {
1278                    jsPopupDateFormat.append('.');
1279                } else if (c == '/') {
1280                    jsPopupDateFormat.append('/');
1281                }
1282            }
1283            return jsPopupDateFormat.toString().trim();
1284        }
1285
1286        /* (non-Javadoc)
1287         * @see javax.faces.convert.Converter#getAsString(javax.faces.context.FacesContext, javax.faces.component.UIComponent, java.lang.Object)
1288         */

1289        public String JavaDoc getAsString(FacesContext facesContext,
1290                                  UIComponent uiComponent, Object JavaDoc o) {
1291            Date JavaDoc date = (Date JavaDoc) o;
1292
1293            if (date == null) {
1294                return null;
1295            }
1296
1297            DateFormat JavaDoc dateFormat = null;
1298
1299            if (uiComponent instanceof SelectInputDate &&
1300                ((SelectInputDate) uiComponent).isRenderAsPopup()) {
1301                String JavaDoc popupDateFormat =
1302                        ((SelectInputDate) uiComponent).getPopupDateFormat();
1303                dateFormat = new SimpleDateFormat JavaDoc(popupDateFormat);
1304            } else {
1305                dateFormat = createStandardDateFormat(facesContext);
1306            }
1307
1308            return dateFormat.format(date);
1309        }
1310
1311        private static SimpleDateFormat JavaDoc createStandardDateFormat(
1312                FacesContext facesContext) {
1313            DateFormat JavaDoc dateFormat;
1314            dateFormat = DateFormat
1315                    .getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT,
1316                                         facesContext
1317                                                 .getViewRoot().getLocale());
1318
1319            if (dateFormat instanceof SimpleDateFormat JavaDoc) {
1320                // BUGFIX for FireFox always create a new dateFormat
1321
// FireFox was reversing the day and month
1322
return new SimpleDateFormat JavaDoc("dd.MM.yyyy");
1323            } else {
1324                return new SimpleDateFormat JavaDoc("dd.MM.yyyy");
1325            }
1326        }
1327
1328    }
1329
1330}
1331
Popular Tags