/*
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* "The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
* License for the specific language governing rights and limitations under
* the License.
*
* The Original Code is ICEfaces 1.5 open source software code, released
* November 5, 2006. The Initial Developer of the Original Code is ICEsoft
* Technologies Canada, Corp. Portions created by ICEsoft are Copyright (C)
* 2004-2006 ICEsoft Technologies Canada, Corp. All Rights Reserved.
*
* Contributor(s): _____________________.
*
* Alternatively, the contents of this file may be used under the terms of
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"
* License), in which case the provisions of the LGPL License are
* applicable instead of those above. If you wish to allow use of your
* version of this file only under the terms of the LGPL License and not to
* allow others to use your version of this file under the MPL, indicate
* your decision by deleting the provisions above and replace them with
* the notice and other provisions required by the LGPL License. If you do
* not delete the provisions above, a recipient may use your version of
* this file under either the MPL or the LGPL License."
*
*/
/* Original Copyright
* Copyright 2004 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.icesoft.faces.component.selectinputdate;
import com.icesoft.faces.context.BridgeFacesContext;
import com.icesoft.faces.component.CSS_DEFAULT;
import com.icesoft.faces.component.ext.HtmlCommandLink;
import com.icesoft.faces.component.ext.HtmlGraphicImage;
import com.icesoft.faces.component.ext.HtmlOutputText;
import com.icesoft.faces.component.ext.HtmlSelectOneMenu;
import com.icesoft.faces.component.ext.renderkit.FormRenderer;
import com.icesoft.faces.component.ext.taglib.Util;
import com.icesoft.faces.component.util.CustomComponentUtils;
import com.icesoft.faces.context.DOMContext;
import com.icesoft.faces.renderkit.dom_html_basic.DomBasicInputRenderer;
import com.icesoft.faces.renderkit.dom_html_basic.HTML;
import com.icesoft.faces.renderkit.dom_html_basic.PassThruAttributeRenderer;
import com.icesoft.faces.util.CoreUtils;
import com.icesoft.faces.utils.MessageUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.w3c.dom.Text;
import javax.faces.component.*;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
import javax.faces.convert.Converter;
import javax.faces.convert.ConverterException;
import javax.faces.event.ActionEvent;
import java.io.IOException;
import java.text.DateFormatSymbols;
import java.text.MessageFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
import java.util.Map;
import java.util.TimeZone;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
*
The SelectInputDateRenderer class is an ICEfaces D2D renderer for the
* SelectInputDate component. Note: This class originally was derived from the
* MyFaces Calendar.
*/
public class SelectInputDateRenderer
extends DomBasicInputRenderer {
// add a static log member
private static final Log log =
LogFactory.getLog(SelectInputDateRenderer.class);
private static final String CALENDAR_TABLE = "_calendarTable";
private static final String CALENDAR_BUTTON = "_calendarButton";
private static final String CALENDAR_POPUP = "_calendarPopup";
private static final String HIDDEN_FIELD_NAME = "showPopup";
private static final String DATE_SELECTED = "dateSelected";
// constants for navigation link ids
private static final String SELECT_MONTH = "_selMo";
private static final String SELECT_YEAR = "_selYr";
private static final String PREV_MONTH = "_prevmo";
private static final String NEXT_MONTH = "_nextmo";
private static final String PREV_YEAR = "_prevyr";
private static final String NEXT_YEAR = "_nextyr";
// constant for selectinputdate links
private static final String CALENDAR = "_calendar_";
private static final String CALENDAR_CLICK = "_calendarClick";
private static final String ROOT_DIV = "_rootDiv";
private static final int IS_NOT = 0;
private static final int IS_CALENDAR_BUTTON = 1;
private static final int IS_CALENDAR = 2;
private static final int IS_PREV_MONTH = 3;
private static final int IS_NEXT_MONTH = 4;
private static final int IS_PREV_YEAR = 5;
private static final int IS_NEXT_YEAR = 6;
private static final String INPUT_TEXT_TITLE =
"com.icesoft.faces.component.selectinputdate.INPUT_TEXT_TITLE";
private static final String CALENDAR_TITLE =
"com.icesoft.faces.component.selectinputdate.CALENDAR_TITLE";
private static final String CALENDAR_SUMMARY =
"com.icesoft.faces.component.selectinputdate.CALENDAR_SUMMARY";
private static final String POPUP_CALENDAR_TITLE =
"com.icesoft.faces.component.selectinputdate.POPUP_CALENDAR_TITLE";
private static final String POPUP_CALENDAR_SUMMARY =
"com.icesoft.faces.component.selectinputdate.POPUP_CALENDAR_SUMMARY";
private static final String YEAR_MONTH_SUMMARY =
"com.icesoft.faces.component.selectinputdate.YEAR_MONTH_SUMMARY";
private static final String OPEN_POPUP_ALT =
"com.icesoft.faces.component.selectinputdate.OPEN_POPUP_ALT";
private static final String OPEN_POPUP_TITLE =
"com.icesoft.faces.component.selectinputdate.OPEN_POPUP_TITLE";
private static final String CLOSE_POPUP_ALT =
"com.icesoft.faces.component.selectinputdate.CLOSE_POPUP_ALT";
private static final String CLOSE_POPUP_TITLE =
"com.icesoft.faces.component.selectinputdate.CLOSE_POPUP_TITLE";
private static final String PREV_YEAR_ALT =
"com.icesoft.faces.component.selectinputdate.PREV_YEAR_ALT";
private static final String PREV_YEAR_TITLE =
"com.icesoft.faces.component.selectinputdate.PREV_YEAR_TITLE";
private static final String NEXT_YEAR_ALT =
"com.icesoft.faces.component.selectinputdate.NEXT_YEAR_ALT";
private static final String NEXT_YEAR_TITLE =
"com.icesoft.faces.component.selectinputdate.NEXT_YEAR_TITLE";
private static final String PREV_MONTH_ALT =
"com.icesoft.faces.component.selectinputdate.PREV_MONTH_ALT";
private static final String PREV_MONTH_TITLE =
"com.icesoft.faces.component.selectinputdate.PREV_MONTH_TITLE";
private static final String NEXT_MONTH_ALT =
"com.icesoft.faces.component.selectinputdate.NEXT_MONTH_ALT";
private static final String NEXT_MONTH_TITLE =
"com.icesoft.faces.component.selectinputdate.NEXT_MONTH_TITLE";
private static final String PREV_YEAR_LABEL =
"com.icesoft.faces.component.selectinputdate.PREV_YEAR_LABEL";
private static final String NEXT_YEAR_LABEL =
"com.icesoft.faces.component.selectinputdate.NEXT_YEAR_LABEL";
private static final int yearListSize = 11;
/* (non-Javadoc)
* @see javax.faces.render.Renderer#getRendersChildren()
*/
public boolean getRendersChildren() {
return true;
}
/* (non-Javadoc)
* @see javax.faces.render.Renderer#encodeChildren(javax.faces.context.FacesContext, javax.faces.component.UIComponent)
*/
public void encodeChildren(FacesContext facesContext,
UIComponent uiComponent) {
}
private String getHiddenFieldName(FacesContext facesContext,
UIComponent uiComponent) {
UIComponent form = findForm(uiComponent);
String formId = form.getClientId(facesContext);
String clientId = uiComponent.getClientId(facesContext);
String hiddenFieldName = formId
+ NamingContainer.SEPARATOR_CHAR
+ UIViewRoot.UNIQUE_ID_PREFIX
+ clientId
+ HIDDEN_FIELD_NAME;
return hiddenFieldName;
}
/* (non-Javadoc)
* @see com.icesoft.faces.renderkit.dom_html_basic.DomBasicRenderer#encodeEnd(javax.faces.context.FacesContext, javax.faces.component.UIComponent)
*/
public void encodeEnd(FacesContext facesContext, UIComponent uiComponent)
throws IOException {
validateParameters(facesContext, uiComponent, SelectInputDate.class);
DOMContext domContext =
DOMContext.attachDOMContext(facesContext, uiComponent);
SelectInputDate selectInputDate = (SelectInputDate) uiComponent;
// get the parentForm
UIComponent parentForm = findForm(selectInputDate);
// if there is no parent form - ERROR
if (parentForm == null) {
log.error("SelectInputDate::must be in a FORM");
return;
}
String clientId;
if (!domContext.isInitialized()) {
Element root = domContext.createRootElement(HTML.DIV_ELEM);
boolean popupState = selectInputDate.isShowPopup();
clientId = uiComponent.getClientId(facesContext);
if (uiComponent.getId() != null)
root.setAttribute("id", clientId + ROOT_DIV);
if (selectInputDate.isRenderAsPopup()) {
if (log.isTraceEnabled()) {
log.trace("Render as popup");
}
// ICE-2492
root.setAttribute(HTML.CLASS_ATTR,
Util.getQualifiedStyleClass(uiComponent, CSS_DEFAULT.DEFAULT_CALENDARPOPUP_CLASS, false));
Element dateText = domContext.createElement(HTML.INPUT_ELEM);
//System.out.println("value: " + selectInputDate.getValue());
dateText.setAttribute(HTML.TYPE_ATTR, HTML.INPUT_TYPE_TEXT); // ICE-2302
dateText.setAttribute(HTML.VALUE_ATTR,
selectInputDate.getTextToRender());
dateText.setAttribute(HTML.ID_ATTR,
clientId + SelectInputDate.CALENDAR_INPUTTEXT);
dateText.setAttribute(HTML.NAME_ATTR,
clientId + SelectInputDate.CALENDAR_INPUTTEXT);
dateText.setAttribute(HTML.CLASS_ATTR,
selectInputDate.getCalendarInputClass());
dateText.setAttribute(HTML.ONFOCUS_ATTR, "setFocus('');");
dateText.setAttribute("onkeypress", this.ICESUBMIT);
String onblur = combinedPassThru(
"setFocus('');",
selectInputDate.getPartialSubmit()?ICESUBMITPARTIAL:null);
dateText.setAttribute(HTML.ONBLUR_ATTR, onblur);
if( selectInputDate.getTabindex() != null ){
dateText.setAttribute(HTML.TABINDEX_ATTR, selectInputDate.getTabindex());
}
if (selectInputDate.getAutocomplete() != null) {
dateText.setAttribute("autocomplete",
selectInputDate.getAutocomplete());
}
String tooltip = null;
tooltip = selectInputDate.getInputTitle();
if(tooltip == null || tooltip.length() == 0) {
// extract the popupdate format and use it as a tooltip
tooltip = getMessageWithParamFromResource(
facesContext, INPUT_TEXT_TITLE,
selectInputDate.getSpecifiedPopupDateFormat());
}
if(tooltip != null && tooltip.length() > 0) {
dateText.setAttribute(HTML.TITLE_ATTR, tooltip);
}
if (selectInputDate.isDisabled()) {
dateText.setAttribute(HTML.DISABLED_ATTR, HTML.DISABLED_ATTR);
}
root.appendChild(dateText);
Element calendarButton =
domContext.createElement(HTML.INPUT_ELEM);
calendarButton
.setAttribute(HTML.ID_ATTR, clientId + CALENDAR_BUTTON);
calendarButton.setAttribute(HTML.NAME_ATTR,
clientId + CALENDAR_BUTTON);
calendarButton.setAttribute(HTML.TYPE_ATTR, "image");
calendarButton.setAttribute(HTML.ONFOCUS_ATTR, "setFocus('');");
// render onclick to set value of hidden field to true
String onClick = "document.forms['" +
parentForm.getClientId(facesContext) + "']['" +
this.getLinkId(facesContext, uiComponent) +
"'].value='" + clientId + CALENDAR_BUTTON +
"';"
+ "document.forms['" +
parentForm.getClientId(facesContext) + "']['" +
getHiddenFieldName(facesContext, uiComponent) +
"'].value='toggle';"
+ "iceSubmitPartial( document.forms['" +
parentForm.getClientId(facesContext) +
"'], this,event); return false;";
calendarButton.setAttribute(HTML.ONCLICK_ATTR, onClick);
if (selectInputDate.isDisabled()) {
calendarButton.setAttribute(HTML.DISABLED_ATTR, HTML.DISABLED_ATTR);
}
root.appendChild(calendarButton);
// render a hidden field to manage the popup state; visible || hidden
FormRenderer.addHiddenField(facesContext, getHiddenFieldName(
facesContext, uiComponent));
String resolvedSrc;
if (popupState) {
if (selectInputDate.isImageDirSet()) {
resolvedSrc = CoreUtils.resolveResourceURL(facesContext,
selectInputDate.getImageDir() + selectInputDate.getClosePopupImage());
} else {
// ICE-2127: allow override of button images via CSS
calendarButton.setAttribute(HTML.CLASS_ATTR, selectInputDate.getClosePopupClass());
// without this Firefox would display a default text on top of the image
resolvedSrc = CoreUtils.resolveResourceURL(facesContext,
selectInputDate.getImageDir() + "spacer.gif");
}
calendarButton.setAttribute(HTML.SRC_ATTR, resolvedSrc );
addAttributeToElementFromResource(facesContext,
CLOSE_POPUP_ALT, calendarButton, HTML.ALT_ATTR);
addAttributeToElementFromResource(facesContext,
CLOSE_POPUP_TITLE, calendarButton, HTML.TITLE_ATTR);
} else {
if (selectInputDate.isImageDirSet()) {
resolvedSrc = CoreUtils.resolveResourceURL(facesContext,
selectInputDate.getImageDir() + selectInputDate.getOpenPopupImage());
} else {
// ICE-2127: allow override of button images via CSS
calendarButton.setAttribute(HTML.CLASS_ATTR, selectInputDate.getOpenPopupClass());
// without this Firefox would display a default text on top of the image
resolvedSrc = CoreUtils.resolveResourceURL(facesContext,
selectInputDate.getImageDir() + "spacer.gif");
}
calendarButton.setAttribute(HTML.SRC_ATTR, resolvedSrc );
addAttributeToElementFromResource(facesContext,
OPEN_POPUP_ALT, calendarButton, HTML.ALT_ATTR);
addAttributeToElementFromResource(facesContext,
OPEN_POPUP_TITLE, calendarButton, HTML.TITLE_ATTR);
FormRenderer.addHiddenField(
facesContext,
parentForm.getClientId(facesContext)+ ":_idcl");
PassThruAttributeRenderer.renderAttributes(
facesContext, uiComponent, new String[] {"title","tabindex"});
domContext.stepOver();
return ;
}
if (!domContext.isStreamWriting()) {
Text br = domContext.createTextNode("
");
root.appendChild(br);
}
Element calendarDiv = domContext.createElement(HTML.DIV_ELEM);
calendarDiv
.setAttribute(HTML.ID_ATTR, clientId + CALENDAR_POPUP);
calendarDiv.setAttribute(HTML.NAME_ATTR,
clientId + CALENDAR_POPUP);
calendarDiv.setAttribute(HTML.STYLE_ELEM,
"position:absolute;z-index:10;");
addAttributeToElementFromResource(facesContext,
POPUP_CALENDAR_TITLE, calendarDiv, HTML.TITLE_ATTR);
Element table = domContext.createElement(HTML.TABLE_ELEM);
table.setAttribute(HTML.ID_ATTR, clientId + CALENDAR_TABLE);
table.setAttribute(HTML.NAME_ATTR, clientId + CALENDAR_TABLE);
table.setAttribute(HTML.CLASS_ATTR,
selectInputDate.getStyleClass());
table.setAttribute(HTML.STYLE_ATTR, "position:absolute;");
table.setAttribute(HTML.CELLPADDING_ATTR, "0");
table.setAttribute(HTML.CELLSPACING_ATTR, "0");
// set mouse events on table bug 372
String mouseOver = selectInputDate.getOnmouseover();
table.setAttribute(HTML.ONMOUSEOVER_ATTR, mouseOver);
String mouseOut = selectInputDate.getOnmouseout();
table.setAttribute(HTML.ONMOUSEOUT_ATTR, mouseOut);
String mouseMove = selectInputDate.getOnmousemove();
table.setAttribute(HTML.ONMOUSEMOVE_ATTR, mouseMove);
addAttributeToElementFromResource(facesContext,
POPUP_CALENDAR_SUMMARY, table, HTML.SUMMARY_ATTR);
calendarDiv.appendChild(table);
Text iframe = domContext.createTextNode("");
calendarDiv.appendChild(iframe);
root.appendChild(calendarDiv);
} else {
if (log.isTraceEnabled()) {
log.trace("Select input Date Normal");
}
Element table = domContext.createElement(HTML.TABLE_ELEM);
table.setAttribute(HTML.ID_ATTR, clientId + CALENDAR_TABLE);
table.setAttribute(HTML.NAME_ATTR, clientId + CALENDAR_TABLE);
table.setAttribute(HTML.CLASS_ATTR,
selectInputDate.getStyleClass());
addAttributeToElementFromResource(facesContext,
CALENDAR_TITLE, table, HTML.TITLE_ATTR);
table.setAttribute(HTML.CELLPADDING_ATTR, "0");
table.setAttribute(HTML.CELLSPACING_ATTR, "0");
// set mouse events on table bug 372
String mouseOver = selectInputDate.getOnmouseover();
table.setAttribute(HTML.ONMOUSEOVER_ATTR, mouseOver);
String mouseOut = selectInputDate.getOnmouseout();
table.setAttribute(HTML.ONMOUSEOUT_ATTR, mouseOut);
String mouseMove = selectInputDate.getOnmousemove();
table.setAttribute(HTML.ONMOUSEMOVE_ATTR, mouseMove);
addAttributeToElementFromResource(facesContext,
CALENDAR_SUMMARY, table, HTML.SUMMARY_ATTR);
root.appendChild(table);
Element dateText = domContext.createElement(HTML.INPUT_ELEM);
dateText.setAttribute(HTML.TYPE_ATTR, HTML.INPUT_TYPE_HIDDEN);
dateText.setAttribute(HTML.VALUE_ATTR,
selectInputDate.getTextToRender());
dateText.setAttribute(HTML.ID_ATTR,
clientId + SelectInputDate.CALENDAR_INPUTTEXT);
dateText.setAttribute(HTML.NAME_ATTR,
clientId + SelectInputDate.CALENDAR_INPUTTEXT);
root.appendChild(dateText);
}
}
clientId = uiComponent.getClientId(facesContext);
Date value;
if (selectInputDate.isNavEvent()) {
if (log.isTraceEnabled()) {
log.trace("Rendering Nav Event");
}
value = selectInputDate.getNavDate();
//System.out.println("navDate: " + value);
} else {
if (log.isTraceEnabled()) {
log.trace("Logging non nav event");
}
value = CustomComponentUtils.getDateValue(selectInputDate);
//System.out.println("CustomComponentUtils.getDateValue: " + value);
}
TimeZone tz = selectInputDate.resolveTimeZone(facesContext);
Locale currentLocale = selectInputDate.resolveLocale(facesContext);
Calendar timeKeeper = Calendar.getInstance(tz, currentLocale);
timeKeeper.setTime(value != null ? value : new Date());
DateFormatSymbols symbols = new DateFormatSymbols(currentLocale);
String[] weekdays = mapWeekdays(symbols);
String[] weekdaysLong = mapWeekdaysLong(symbols);
String[] months = mapMonths(symbols);
// use the currentDay to set focus - do not set
int lastDayInMonth = timeKeeper.getActualMaximum(Calendar.DAY_OF_MONTH);
int currentDay = timeKeeper.get(Calendar.DAY_OF_MONTH); // starts at 1
if (currentDay > lastDayInMonth) {
currentDay = lastDayInMonth;
}
timeKeeper.set(Calendar.DAY_OF_MONTH, 1);
int weekDayOfFirstDayOfMonth =
mapCalendarDayToCommonDay(timeKeeper.get(Calendar.DAY_OF_WEEK));
int weekStartsAtDayIndex =
mapCalendarDayToCommonDay(timeKeeper.getFirstDayOfWeek());
// do not require a writer - clean out all methods that reference a writer
ResponseWriter writer = facesContext.getResponseWriter();
Element root = (Element) domContext.getRootNode();
if (selectInputDate.isRenderAsPopup()) {
if (log.isTraceEnabled()) {
log.trace("SelectInputDate as Popup");
}
// assumption input text is first child
Element dateText = (Element) root.getFirstChild();
//System.out.println("dateText currentValue: " + currentValue);
dateText.setAttribute(HTML.TYPE_ATTR, HTML.INPUT_TYPE_TEXT); // ICE-2302
dateText.setAttribute(
HTML.VALUE_ATTR,
selectInputDate.getTextToRender());
// get tables , our table is the first and only one
NodeList tables = root.getElementsByTagName(HTML.TABLE_ELEM);
// assumption we want the first table in tables. there should only be one
Element table = (Element) tables.item(0);
PassThruAttributeRenderer.renderAttributes(
facesContext, uiComponent, new String[] {"title"});
Element tr1 = domContext.createElement(HTML.TR_ELEM);
table.appendChild(tr1);
writeMonthYearHeader(domContext, facesContext, writer,
selectInputDate, timeKeeper,
currentDay, tr1,
selectInputDate.getMonthYearRowClass(),
currentLocale, months, weekdays, weekdaysLong);
Element tr2 = domContext.createElement(HTML.TR_ELEM);
table.appendChild(tr2);
writeWeekDayNameHeader(domContext, weekStartsAtDayIndex, weekdays,
facesContext, writer, selectInputDate, tr2,
selectInputDate.getWeekRowClass(),
timeKeeper, months, weekdaysLong);
writeDays(domContext, facesContext, writer, selectInputDate,
timeKeeper,
currentDay, weekStartsAtDayIndex,
weekDayOfFirstDayOfMonth,
lastDayInMonth, table,
months, weekdays, weekdaysLong);
} else {
if (log.isTraceEnabled()) {
log.trace("renderNormal::endcodeEnd");
}
// assume table is the first child
Element table = (Element) root.getFirstChild();
PassThruAttributeRenderer.renderAttributes(
facesContext, uiComponent, new String[] {"title"});
Element tr1 = domContext.createElement(HTML.TR_ELEM);
table.appendChild(tr1);
writeMonthYearHeader(domContext, facesContext, writer,
selectInputDate, timeKeeper,
currentDay, tr1,
selectInputDate.getMonthYearRowClass(),
currentLocale, months, weekdays, weekdaysLong);
Element tr2 = domContext.createElement(HTML.TR_ELEM);
writeWeekDayNameHeader(domContext, weekStartsAtDayIndex, weekdays,
facesContext, writer, selectInputDate, tr2,
selectInputDate.getWeekRowClass(),
timeKeeper, months, weekdaysLong);
table.appendChild(tr2);
writeDays(domContext, facesContext, writer, selectInputDate,
timeKeeper,
currentDay, weekStartsAtDayIndex,
weekDayOfFirstDayOfMonth,
lastDayInMonth, table,
months, weekdays, weekdaysLong);
}
// purge child components as they have been encoded no need to keep them around
selectInputDate.getChildren().removeAll(selectInputDate.getChildren());
// steps to the position where the next sibling should be rendered
domContext.stepOver();
domContext.streamWrite(facesContext, uiComponent);
}
private void writeMonthYearHeader(DOMContext domContext,
FacesContext facesContext,
ResponseWriter writer,
SelectInputDate inputComponent,
Calendar timeKeeper,
int currentDay, Element headerTr,
String styleClass, Locale currentLocale,
String[] months, String[] weekdays, String[] weekdaysLong)
throws IOException {
Element table = domContext.createElement(HTML.TABLE_ELEM);
table.setAttribute(HTML.CELLPADDING_ATTR, "0");
table.setAttribute(HTML.CELLSPACING_ATTR, "0");
table.setAttribute(HTML.WIDTH_ATTR, "100%");
addAttributeToElementFromResource(facesContext,
YEAR_MONTH_SUMMARY, table, HTML.SUMMARY_ATTR);
Element tr = domContext.createElement(HTML.TR_ELEM);
Element headertd = domContext.createElement(HTML.TD_ELEM);
table.appendChild(tr);
headertd.appendChild(table);
headerTr.appendChild(headertd);
headertd.setAttribute(HTML.COLSPAN_ATTR, "7"); // weekdays.length = 7
int calYear = timeKeeper.get(Calendar.YEAR);
if (inputComponent.getHightlightRules().containsKey(Calendar.YEAR + "$" + calYear)) {
inputComponent.setHighlightYearClass(inputComponent.getHightlightRules().get(Calendar.YEAR + "$" + calYear) + " ");
} else {
inputComponent.setHighlightYearClass("");
}
int calMonth = timeKeeper.get(Calendar.MONTH) + 1;
if (inputComponent.getHightlightRules().containsKey(Calendar.MONTH + "$" + calMonth)) {
inputComponent.setHighlightMonthClass(inputComponent.getHightlightRules().get(Calendar.MONTH + "$" + calMonth) + " ");
} else {
inputComponent.setHighlightMonthClass("");
}
// first render month with navigation back and forward
if (inputComponent.isRenderMonthAsDropdown()) {
writeMonthDropdown(facesContext, domContext, inputComponent, tr, months, timeKeeper, currentDay, styleClass);
} else {
Calendar cal = shiftMonth(facesContext, timeKeeper, currentDay, -1);
writeCell(domContext, facesContext, writer, inputComponent,
"<", cal.getTime(), styleClass, tr,
inputComponent.getImageDir() +
inputComponent.getMovePreviousImage(), -1,
timeKeeper, months, weekdaysLong);
Element td = domContext.createElement(HTML.TD_ELEM);
td.setAttribute(HTML.CLASS_ATTR, styleClass);
td.setAttribute(HTML.WIDTH_ATTR, "40%");
Text text = domContext
.createTextNode(months[timeKeeper.get(Calendar.MONTH)] + "");
td.appendChild(text);
tr.appendChild(td);
cal = shiftMonth(facesContext, timeKeeper, currentDay, 1);
/*
int calYear = cal.get(Calendar.YEAR);
if (inputComponent.getHightlightRules().containsKey(Calendar.YEAR+"$"+calYear)) {
inputComponent.setHighlightYearClass(inputComponent.getHightlightRules().get(Calendar.YEAR+"$"+calYear) + " ");
} else {
inputComponent.setHighlightYearClass("");
}
int calMonth = cal.get(Calendar.MONTH);
if (inputComponent.getHightlightRules().containsKey(Calendar.MONTH+"$"+calMonth)) {
inputComponent.setHighlightMonthClass(inputComponent.getHightlightRules().get(Calendar.MONTH+"$"+calMonth) + " ");
} else {
inputComponent.setHighlightMonthClass("");
}
*/
writeCell(domContext, facesContext, writer, inputComponent,
">", cal.getTime(), styleClass, tr,
inputComponent.getImageDir() +
inputComponent.getMoveNextImage(), -1,
timeKeeper, months, weekdaysLong);
}
// second add an empty td
Element emptytd = domContext.createElement(HTML.TD_ELEM);
emptytd.setAttribute(HTML.CLASS_ATTR, styleClass);
Text emptytext = domContext.createTextNode("");
emptytd.appendChild(emptytext);
tr.appendChild(emptytd);
// third render year with navigation back and forward
if (inputComponent.isRenderYearAsDropdown()) {
writeYearDropdown(facesContext, domContext, inputComponent, tr, timeKeeper, currentDay, styleClass);
} else {
Calendar cal = shiftYear(facesContext, timeKeeper, currentDay, -1);
writeCell(domContext, facesContext, writer, inputComponent,
"<<", cal.getTime(), styleClass, tr,
inputComponent.getImageDir() +
inputComponent.getMovePreviousImage(), -1,
timeKeeper, months, weekdaysLong);
Element yeartd = domContext.createElement(HTML.TD_ELEM);
yeartd.setAttribute(HTML.CLASS_ATTR, styleClass);
Text yeartext =
domContext.createTextNode("" + timeKeeper.get(Calendar.YEAR));
yeartd.appendChild(yeartext);
tr.appendChild(yeartd);
cal = shiftYear(facesContext, timeKeeper, currentDay, 1);
writeCell(domContext, facesContext, writer, inputComponent,
">>", cal.getTime(), styleClass, tr,
inputComponent.getImageDir() +
inputComponent.getMoveNextImage(), -1,
timeKeeper, months, weekdaysLong);
}
}
private void writeMonthDropdown(FacesContext facesContext,
DOMContext domContext,
SelectInputDate component,
Element tr,
String[] months,
Calendar timeKeeper,
int currentDay,
String styleClass) throws IOException {
Element td = domContext.createElement(HTML.TD_ELEM);
if (styleClass != null) {
td.setAttribute(HTML.CLASS_ATTR, styleClass);
}
tr.appendChild(td);
domContext.setCursorParent(td);
domContext.streamWrite(facesContext, component, domContext.getRootNode(), td);
HtmlSelectOneMenu dropDown = new HtmlSelectOneMenu();
dropDown.setId(component.getId() + SELECT_MONTH);
dropDown.setPartialSubmit(true);
dropDown.setTransient(true);
dropDown.setImmediate(component.isImmediate());
dropDown.setDisabled(component.isDisabled());
dropDown.setStyleClass(component.getMonthYearDropdownClass());
UISelectItem selectItem;
Calendar calendar;
int currentMonth = timeKeeper.get(Calendar.MONTH);
Converter converter = component.resolveDateTimeConverter(facesContext);
for (int i = 0; i < months.length; i++) {
selectItem = new UISelectItem();
calendar = shiftMonth(facesContext, timeKeeper, currentDay, i - currentMonth);
selectItem.setItemValue(converter.getAsString(facesContext, component, calendar.getTime()));
selectItem.setItemLabel(months[i]);
dropDown.getChildren().add(selectItem);
if (i == currentMonth) {
dropDown.setValue(selectItem.getItemValue());
}
}
component.getChildren().add(dropDown);
dropDown.encodeBegin(facesContext);
dropDown.encodeChildren(facesContext);
dropDown.encodeEnd(facesContext);
component.getChildren().remove(dropDown);
domContext.stepOver();
}
private void writeYearDropdown(FacesContext facesContext,
DOMContext domContext,
SelectInputDate component,
Element tr,
Calendar timeKeeper,
int currentDay,
String styleClass) throws IOException {
Element td = domContext.createElement(HTML.TD_ELEM);
if (styleClass != null) {
td.setAttribute(HTML.CLASS_ATTR, styleClass);
}
tr.appendChild(td);
domContext.setCursorParent(td);
domContext.streamWrite(facesContext, component, domContext.getRootNode(), td);
HtmlSelectOneMenu dropDown = new HtmlSelectOneMenu();
dropDown.setId(component.getId() + SELECT_YEAR);
dropDown.setPartialSubmit(true);
dropDown.setTransient(true);
dropDown.setImmediate(component.isImmediate());
dropDown.setDisabled(component.isDisabled());
dropDown.setStyleClass(component.getMonthYearDropdownClass());
int timeKeeperYear = timeKeeper.get(Calendar.YEAR);
int startYear = timeKeeperYear - yearListSize / 2; // not perfectly centered if size is even
Converter converter = component.resolveDateTimeConverter(facesContext);
UISelectItem selectItem;
Calendar calendar;
String itemValue, itemLabel;
for (int i = startYear - 1, j = i, k = startYear + yearListSize; i <= k; i++) {
if (i == j) {
calendar = shiftYear(facesContext, timeKeeper, currentDay, -yearListSize);
itemLabel = MessageUtils.getResource(facesContext, PREV_YEAR_LABEL);
} else if (i == k) {
calendar = shiftYear(facesContext, timeKeeper, currentDay, yearListSize);
itemLabel = MessageUtils.getResource(facesContext, NEXT_YEAR_LABEL);
} else {
calendar = shiftYear(facesContext, timeKeeper, currentDay, i - timeKeeperYear);
itemLabel = String.valueOf(calendar.get(Calendar.YEAR));
}
itemValue = converter.getAsString(facesContext, component, calendar.getTime());
selectItem = new UISelectItem();
selectItem.setItemValue(itemValue);
selectItem.setItemLabel(itemLabel);
dropDown.getChildren().add(selectItem);
if (i == timeKeeperYear) {
dropDown.setValue(itemValue);
}
}
component.getChildren().add(dropDown);
dropDown.encodeBegin(facesContext);
dropDown.encodeChildren(facesContext);
dropDown.encodeEnd(facesContext);
component.getChildren().remove(dropDown);
domContext.stepOver();
}
private Calendar shiftMonth(FacesContext facesContext,
Calendar timeKeeper, int currentDay,
int shift) {
Calendar cal = copyCalendar(facesContext, timeKeeper);
cal.set(Calendar.MONTH, cal.get(Calendar.MONTH) + shift);
if (currentDay > cal.getActualMaximum(Calendar.DAY_OF_MONTH)) {
currentDay = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
}
cal.set(Calendar.DAY_OF_MONTH, currentDay);
return cal;
}
private Calendar shiftYear(FacesContext facesContext,
Calendar timeKeeper, int currentDay, int shift) {
Calendar cal = copyCalendar(facesContext, timeKeeper);
cal.set(Calendar.YEAR, cal.get(Calendar.YEAR) + shift);
if (currentDay > cal.getActualMaximum(Calendar.DAY_OF_MONTH)) {
currentDay = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
}
cal.set(Calendar.DAY_OF_MONTH, currentDay);
return cal;
}
private Calendar copyCalendar(FacesContext facesContext,
Calendar timeKeeper) {
Calendar cal = (Calendar) timeKeeper.clone();
return cal;
}
private void writeWeekDayNameHeader(DOMContext domContext,
int weekStartsAtDayIndex,
String[] weekdays,
FacesContext facesContext,
ResponseWriter writer,
SelectInputDate inputComponent, Element tr,
String styleClass,
Calendar timeKeeper,
String[] months, String[] weekdaysLong)
throws IOException {
// the week can start with Sunday (index 0) or Monday (index 1)
for (int i = weekStartsAtDayIndex; i < weekdays.length; i++) {
writeCell(domContext, facesContext,
writer, inputComponent, weekdays[i], null, styleClass, tr,
null, i,
timeKeeper, months, weekdaysLong);
}
// if week start on Sunday this block is not executed
// if week start on Monday this block will run once adding Sunday to End of week.
for (int i = 0; i < weekStartsAtDayIndex; i++) {
writeCell(domContext, facesContext, writer,
inputComponent, weekdays[i], null, styleClass, tr, null, i,
timeKeeper, months, weekdaysLong);
}
}
private void writeDays(DOMContext domContext, FacesContext facesContext,
ResponseWriter writer,
SelectInputDate inputComponent, Calendar timeKeeper,
int currentDay, int weekStartsAtDayIndex,
int weekDayOfFirstDayOfMonth, int lastDayInMonth,
Element table, String[] months,
String[] weekdays, String[] weekdaysLong)
throws IOException {
Calendar cal;
int space = (weekStartsAtDayIndex < weekDayOfFirstDayOfMonth) ?
(weekDayOfFirstDayOfMonth - weekStartsAtDayIndex)
: (weekdays.length - weekStartsAtDayIndex +
weekDayOfFirstDayOfMonth);
if (space == weekdays.length) {
space = 0;
}
int columnIndexCounter = 0;
Element tr1 = null;
for (int i = 0; i < space; i++) {
if (columnIndexCounter == 0) {
tr1 = domContext.createElement(HTML.TR_ELEM);
table.appendChild(tr1);
}
writeCell(domContext, facesContext, writer, inputComponent, " ",
null, inputComponent.getDayCellClass(), tr1, null,
(weekStartsAtDayIndex + i) % 7,
timeKeeper, months, weekdaysLong);
columnIndexCounter++;
}
Element tr2 = null;
for (int i = 0; i < lastDayInMonth; i++) {
if (columnIndexCounter == 0) {
// don't create a new row until we have finished the last
tr2 = domContext.createElement(HTML.TR_ELEM);
table.appendChild(tr2);
}
cal = copyCalendar(facesContext, timeKeeper);
cal.set(Calendar.DAY_OF_MONTH,
i + 1); // i starts at 0 DAY_OF_MONTH start at 1
// get day, month and year
// use these to check if the currentDayCell style class should be used
int day = 0;
int month = 0;
int year = 0;
try {
Date currentDate = (Date) inputComponent.getValue();
Calendar current = copyCalendar(facesContext, timeKeeper);
current.setTime(currentDate);
day = current.get(Calendar.DAY_OF_MONTH); // starts with 1
month = current.get(Calendar.MONTH); // starts with 0
year = current.get(Calendar.YEAR);
} catch (Exception e) {
// hmmm this should never happen
}
if (inputComponent.getHightlightRules().size()>0) {
int weekOfYear = cal.get(Calendar.WEEK_OF_YEAR);
int weekOfMonth = cal.get(Calendar.WEEK_OF_MONTH);
int date =cal.get(Calendar.DATE);
int dayOfYear = cal.get(Calendar.DAY_OF_YEAR);
int dayOfWeek = cal.get(Calendar.DAY_OF_WEEK);
int dayOfWeekInMonth = cal.get(Calendar.DAY_OF_WEEK_IN_MONTH);
if (inputComponent.getHightlightRules().containsKey(Calendar.WEEK_OF_YEAR+"$"+weekOfYear)) {
inputComponent.addHighlightWeekClass(String.valueOf(inputComponent.getHightlightRules().get(Calendar.WEEK_OF_YEAR+"$"+weekOfYear)));
}
if (inputComponent.getHightlightRules().containsKey(Calendar.WEEK_OF_MONTH+"$"+weekOfMonth)) {
inputComponent.addHighlightWeekClass(String.valueOf(inputComponent.getHightlightRules().get(Calendar.WEEK_OF_MONTH+"$"+weekOfMonth)));
}
if (inputComponent.getHightlightRules().containsKey(Calendar.DATE+"$"+date)) {
inputComponent.addHighlightDayClass(String.valueOf(inputComponent.getHightlightRules().get(Calendar.DATE+"$"+date)));
}
if (inputComponent.getHightlightRules().containsKey(Calendar.DAY_OF_YEAR+"$"+dayOfYear)) {
inputComponent.addHighlightDayClass(String.valueOf(inputComponent.getHightlightRules().get(Calendar.DAY_OF_YEAR+"$"+dayOfYear)));
}
if (inputComponent.getHightlightRules().containsKey(Calendar.DAY_OF_WEEK+"$"+dayOfWeek)) {
inputComponent.addHighlightDayClass(String.valueOf(inputComponent.getHightlightRules().get(Calendar.DAY_OF_WEEK+"$"+dayOfWeek)));
}
if (inputComponent.getHightlightRules().containsKey(Calendar.DAY_OF_WEEK_IN_MONTH+"$"+dayOfWeekInMonth)) {
inputComponent.addHighlightDayClass(String.valueOf(inputComponent.getHightlightRules().get(Calendar.DAY_OF_WEEK_IN_MONTH+"$"+dayOfWeekInMonth)));
}
}
String cellStyle = inputComponent.getDayCellClass() + " " + inputComponent.getHighlightDayCellClass();
if ((cal.get(Calendar.DAY_OF_MONTH) == day) &&
(cal.get(Calendar.MONTH) == month) &&
(cal.get(Calendar.YEAR) == year)) {
cellStyle = inputComponent.getCurrentDayCellClass();
}
// do not automatically select date when navigating by month
if ((cal.get(Calendar.DAY_OF_MONTH) == day) &&
(cal.get(Calendar.MONTH) == month) &&
(cal.get(Calendar.YEAR) == year)) {
cellStyle = inputComponent.getCurrentDayCellClass();
}
if (tr2 == null) {
// finish the first row
writeCell(domContext, facesContext, writer,
inputComponent, String.valueOf(i + 1), cal.getTime(),
cellStyle, tr1, null, i,
timeKeeper, months, weekdaysLong);
} else {
// write to new row
writeCell(domContext, facesContext, writer,
inputComponent, String.valueOf(i + 1), cal.getTime(),
cellStyle, tr2, null, i,
timeKeeper, months, weekdaysLong);
}
columnIndexCounter++;
if (columnIndexCounter == weekdays.length) {
columnIndexCounter = 0;
}
inputComponent.resetHighlightClasses(Calendar.WEEK_OF_YEAR);
}
if ((columnIndexCounter != 0) && (tr2 != null)) {
for (int i = columnIndexCounter; i < weekdays.length; i++) {
writeCell(domContext, facesContext, writer,
inputComponent, " ", null,
inputComponent.getDayCellClass(), tr2, null,
(weekStartsAtDayIndex + i) % 7,
timeKeeper, months, weekdaysLong);
}
}
}
private void writeCell(DOMContext domContext, FacesContext facesContext,
ResponseWriter writer, SelectInputDate component,
String content,
Date valueForLink, String styleClass, Element tr,
String imgSrc, int weekDayIndex,
Calendar timeKeeper,
String[] months, String[] weekdaysLong)
throws IOException {
Element td = domContext.createElement(HTML.TD_ELEM);
tr.appendChild(td);
if (styleClass != null) {
td.setAttribute(HTML.CLASS_ATTR, styleClass);
}
if (valueForLink == null) {
if(content != null && content.length() > 0) {
Text text = domContext.createTextNode(content);
td.setAttribute(HTML.TITLE_ATTR,weekdaysLong[weekDayIndex]);
td.appendChild(text);
}
} else {
// set cursor to render into the td
domContext.setCursorParent(td);
domContext.streamWrite(facesContext, component,
domContext.getRootNode(), td);
writeLink(content, component, facesContext, valueForLink,
styleClass, imgSrc, td, timeKeeper,
months, weekdaysLong);
// steps to the position where the next sibling should be rendered
domContext.stepOver();
}
}
private void writeLink(String content,
SelectInputDate component,
FacesContext facesContext,
Date valueForLink,
String styleClass,
String imgSrc,
Element td,
Calendar timeKeeper,
String[] months, String[] weekdaysLong)
throws IOException {
Converter converter = component.resolveDateTimeConverter(facesContext);
HtmlCommandLink link = new HtmlCommandLink();
Calendar cal = copyCalendar(facesContext, timeKeeper);
cal.setTime(valueForLink);
String month = months[cal.get(Calendar.MONTH)];
String year = String.valueOf(cal.get(Calendar.YEAR));
int dayInt = cal.get(Calendar.DAY_OF_WEEK);
dayInt = mapCalendarDayToCommonDay(dayInt);
String day = weekdaysLong[dayInt];
String altText = null;
String titleText = null;
// assign special ids for navigation links
if (content.equals("<")) {
link.setId(component.getId() + this.PREV_MONTH);
altText = getMessageWithParamFromResource(
facesContext, PREV_MONTH_ALT, month);
titleText = getMessageWithParamFromResource(
facesContext, PREV_MONTH_TITLE, month);
} else if (content.equals(">")) {
link.setId(component.getId() + this.NEXT_MONTH);
altText = getMessageWithParamFromResource(
facesContext, NEXT_MONTH_ALT, month);
titleText = getMessageWithParamFromResource(
facesContext, NEXT_MONTH_TITLE, month);
} else if (content.equals(">>")) {
link.setId(component.getId() + this.NEXT_YEAR);
altText = getMessageWithParamFromResource(
facesContext, NEXT_YEAR_ALT, year);
titleText = getMessageWithParamFromResource(
facesContext, NEXT_YEAR_TITLE, year);
} else if (content.equals("<<")) {
link.setId(component.getId() + this.PREV_YEAR);
altText = getMessageWithParamFromResource(
facesContext, PREV_YEAR_ALT, year);
titleText = getMessageWithParamFromResource(
facesContext, PREV_YEAR_TITLE, year);
} else {
link.setId(component.getId() + CALENDAR + content.hashCode());
if (log.isDebugEnabled()) {
log.debug("linkId=" +
component.getId() + CALENDAR + content.hashCode());
}
}
link.setPartialSubmit(true);
link.setTransient(true);
link.setImmediate(component.isImmediate());
link.setDisabled(((SelectInputDate) component).isDisabled());
if (imgSrc != null) {
HtmlGraphicImage img = new HtmlGraphicImage();
if (component.isImageDirSet()) {
img.setUrl(imgSrc);
} else {
// ICE-2127: allow override of button images via CSS
// getImageDir() returns default
// without a dummy image Firefox would show the alt text
img.setUrl(component.getImageDir() + "spacer.gif");
if (content.equals("<") || content.equals("<<")) {
img.setStyleClass(component.getMovePrevClass());
} else if (content.equals(">") || content.equals(">>")) {
img.setStyleClass(component.getMoveNextClass());
}
}
img.setHeight("16");
img.setWidth("17");
img.setStyle("border:none;");
if(altText != null)
img.setAlt(altText);
if(titleText != null)
img.setTitle(titleText);
img.setId(component.getId() + "_img_" + content.hashCode());
img.setTransient(true);
link.getChildren().add(img);
} else {
HtmlOutputText text = new HtmlOutputText();
text.setValue(content);
text.setId(component.getId() + "_text_" + content.hashCode());
text.setTransient(true);
text.setTitle(day);
link.getChildren().add(text);
}
// links are focus aware
UIParameter parameter = new UIParameter();
parameter.setId(
component.getId() + "_" + valueForLink.getTime() + "_param");
parameter.setTransient(true);
parameter.setName(component.getClientId(facesContext) + CALENDAR_CLICK);
parameter.setValue(
converter.getAsString(facesContext, component, valueForLink));
component.getChildren().add(link);
link.getChildren().add(parameter);
//don't add this parameter for next and previouse button/link
if (!content.equals("<") && !content.equals(">") &&
!content.equals(">>") && !content.equals("<<")) {
//this parameter would be use to close the popup selectinputdate after date selection.
parameter = new UIParameter();
parameter.setId(component.getId() + "_" + valueForLink.getTime() +
"_" + DATE_SELECTED);
parameter.setName(getHiddenFieldName(facesContext, component));
parameter.setValue("false");
link.getChildren().add(parameter);
}
link.encodeBegin(facesContext);
link.encodeChildren(facesContext);
link.encodeEnd(facesContext);
td.setAttribute(HTML.ID_ATTR, link.getClientId(facesContext) + "td");
try {
Integer.parseInt(content);
((SelectInputDate) component).getLinkMap()
.put(link.getClientId(facesContext), td);
if (styleClass.equals(CSS_DEFAULT.DEFAULT_CALENDAR + CSS_DEFAULT
.DEFAULT_CURRENTDAYCELL_CLASS)) {
((SelectInputDate) component)
.setSelectedDayLink(link.getClientId(facesContext));
}
} catch (NumberFormatException e) {
}
}
protected void addAttributeToElementFromResource(
FacesContext facesContext, String resName, Element elem, String attrib)
{
String res = MessageUtils.getResource(facesContext, resName);
if(res != null && res.length() > 0) {
elem.setAttribute(attrib, res);
}
}
protected String getMessageWithParamFromResource(
FacesContext facesContext, String resName, String param)
{
String msg = null;
if(param != null && param.length() > 0) {
String messagePattern = MessageUtils.getResource(
facesContext, resName);
if(messagePattern != null && messagePattern.length() > 0) {
msg = MessageFormat.format(
messagePattern, new Object[] {param});
}
}
return msg;
}
private int mapCalendarDayToCommonDay(int day) {
switch (day) {
case Calendar.TUESDAY:
return 1;
case Calendar.WEDNESDAY:
return 2;
case Calendar.THURSDAY:
return 3;
case Calendar.FRIDAY:
return 4;
case Calendar.SATURDAY:
return 5;
case Calendar.SUNDAY:
return 6;
default:
return 0;
}
}
private static String[] mapWeekdays(DateFormatSymbols symbols) {
String[] weekdays = new String[7];
String[] localeWeekdays = symbols.getShortWeekdays();
weekdays[0] = localeWeekdays[Calendar.MONDAY];
weekdays[1] = localeWeekdays[Calendar.TUESDAY];
weekdays[2] = localeWeekdays[Calendar.WEDNESDAY];
weekdays[3] = localeWeekdays[Calendar.THURSDAY];
weekdays[4] = localeWeekdays[Calendar.FRIDAY];
weekdays[5] = localeWeekdays[Calendar.SATURDAY];
weekdays[6] = localeWeekdays[Calendar.SUNDAY];
return weekdays;
}
private static String[] mapWeekdaysLong(DateFormatSymbols symbols) {
String[] weekdays = new String[7];
String[] localeWeekdays = symbols.getWeekdays();
weekdays[0] = localeWeekdays[Calendar.MONDAY];
weekdays[1] = localeWeekdays[Calendar.TUESDAY];
weekdays[2] = localeWeekdays[Calendar.WEDNESDAY];
weekdays[3] = localeWeekdays[Calendar.THURSDAY];
weekdays[4] = localeWeekdays[Calendar.FRIDAY];
weekdays[5] = localeWeekdays[Calendar.SATURDAY];
weekdays[6] = localeWeekdays[Calendar.SUNDAY];
return weekdays;
}
/**
* @param symbols
* @return months - String[] containing localized month names
*/
public static String[] mapMonths(DateFormatSymbols symbols) {
String[] months = new String[12];
String[] localeMonths = symbols.getMonths();
months[0] = localeMonths[Calendar.JANUARY];
months[1] = localeMonths[Calendar.FEBRUARY];
months[2] = localeMonths[Calendar.MARCH];
months[3] = localeMonths[Calendar.APRIL];
months[4] = localeMonths[Calendar.MAY];
months[5] = localeMonths[Calendar.JUNE];
months[6] = localeMonths[Calendar.JULY];
months[7] = localeMonths[Calendar.AUGUST];
months[8] = localeMonths[Calendar.SEPTEMBER];
months[9] = localeMonths[Calendar.OCTOBER];
months[10] = localeMonths[Calendar.NOVEMBER];
months[11] = localeMonths[Calendar.DECEMBER];
return months;
}
/**
* @param facesContext
* @param uiComponent
* @return id - used for the commandlink hidden field in the form
*/
public String getLinkId(FacesContext facesContext,
UIComponent uiComponent) {
//this is a fix for bug 340
UIComponent form = findForm(uiComponent);
String formId = form.getClientId(facesContext);
return formId + ":_idcl";
}
private int checkLink(String clickedLink, String clientId) {
if (clickedLink == null) {
return IS_NOT;
}
else if( (clientId+CALENDAR_BUTTON).equals(clickedLink) ) {
return IS_CALENDAR_BUTTON;
}
else if( clickedLink.startsWith(clientId+CALENDAR) ) {
return IS_CALENDAR;
}
else if( (clientId+PREV_MONTH).equals(clickedLink) ) {
return IS_PREV_MONTH;
}
else if( (clientId+NEXT_MONTH).equals(clickedLink) ) {
return IS_NEXT_MONTH;
}
else if( (clientId+PREV_YEAR).equals(clickedLink) ) {
return IS_PREV_YEAR;
}
else if( (clientId+NEXT_YEAR).equals(clickedLink) ) {
return IS_NEXT_YEAR;
}
return IS_NOT;
}
/* (non-Javadoc)
* @see com.icesoft.faces.renderkit.dom_html_basic.DomBasicRenderer#decode(javax.faces.context.FacesContext, javax.faces.component.UIComponent)
*/
public void decode(FacesContext facesContext, UIComponent component) {
validateParameters(facesContext, component, SelectInputDate.class);
SelectInputDate dateSelect = (SelectInputDate) component;
Map requestParameterMap =
facesContext.getExternalContext().getRequestParameterMap();
Object linkId = getLinkId(facesContext, component);
Object clickedLink = requestParameterMap.get(linkId);
String clientId = component.getClientId(facesContext);
//System.out.println("SIDR.decode() clientId: " + clientId);
Object eventCapturedId = requestParameterMap.get("ice.event.captured");
String monthClientId = clientId + SELECT_MONTH;
String yearClientId = clientId + SELECT_YEAR;
if (monthClientId.equals(eventCapturedId)) {
dateSelect.setNavEvent(true);
dateSelect.setNavDate((Date) getConvertedValue(facesContext, component, requestParameterMap.get(monthClientId)));
}
else if (yearClientId.equals(eventCapturedId)) {
dateSelect.setNavEvent(true);
dateSelect.setNavDate((Date) getConvertedValue(facesContext, component, requestParameterMap.get(yearClientId)));
}
else if (clickedLink != null) {
if (log.isDebugEnabled()) {
log.debug("linkId::" + linkId + " clickedLink::" +
clickedLink + " clientId::" + clientId);
}
String sclickedLink = (String) clickedLink;
int check = checkLink(sclickedLink, clientId);
if (check != IS_NOT) {
if (log.isDebugEnabled()) {
log.debug("---------------------------------");
log.debug("----------START::DECODE----------");
log.debug("---------------------------------");
log.debug("decode::linkId::" + linkId + "=" + clickedLink +
" clientId::" + clientId);
}
if (check == IS_PREV_MONTH ||
check == IS_NEXT_MONTH ||
check == IS_PREV_YEAR ||
check == IS_NEXT_YEAR) {
if (log.isDebugEnabled()) {
log.debug("-------------Navigation Event-------------");
}
decodeNavigation(facesContext, component);
} else if (check == IS_CALENDAR) {
if (log.isDebugEnabled()) {
log.debug(
"-------------Select Date Event-------------");
}
decodeSelectDate(facesContext, component);
} else if (check == IS_CALENDAR_BUTTON) {
if (log.isDebugEnabled()) {
log.debug(
"-------------Popup Event-------------------");
}
decodePopup(facesContext, component);
}
} else {
if (log.isDebugEnabled()) {
log.debug("-------------InputText enterkey Event ??----");
}
boolean enterKeyPressed = false;
if (requestParameterMap.get("ice.event.target") != null ) {
enterKeyPressed = requestParameterMap.get("ice.event.target")
.equals(clientId + SelectInputDate.CALENDAR_INPUTTEXT) &&
("13".equalsIgnoreCase(String.valueOf
(requestParameterMap.get("ice.event.keycode"))) ||
"onblur".equalsIgnoreCase(String.valueOf
(requestParameterMap.get("ice.event.type"))));
}
decodeInputText(facesContext, component);
if (enterKeyPressed) {
component.queueEvent(new ActionEvent(component));
}
}
}
}
private void decodeNavigation(FacesContext facesContext,
UIComponent component) {
Map requestParameterMap =
facesContext.getExternalContext().getRequestParameterMap();
SelectInputDate dateSelect = (SelectInputDate) component;
// set the navDate on the Calendar
if (log.isDebugEnabled()) {
log.debug("setNavDate::");
log.debug("#################################");
}
dateSelect.setNavEvent(true);
dateSelect.setNavDate(
(Date) getConvertedValue(
facesContext, dateSelect, requestParameterMap.get(
dateSelect.getClientId(facesContext) + CALENDAR_CLICK)));
}
private void decodePopup(FacesContext facesContext, UIComponent component) {
Map requestParameterMap =
facesContext.getExternalContext().getRequestParameterMap();
String popupState = getHiddenFieldName(facesContext, component);
String showPopup = (String) requestParameterMap.get(popupState);
SelectInputDate dateSelect = (SelectInputDate) component;
if (log.isDebugEnabled()) {
log.debug("decodePopup::" + showPopup);
log.debug("#################################");
}
// check showPopup
if (showPopup != null) {
dateSelect.setShowPopup(!dateSelect.isShowPopup());
}
// not a nav event
dateSelect.setNavEvent(false);
}
private void decodeSelectDate(FacesContext facesContext,
UIComponent component) {
Map requestParameterMap =
facesContext.getExternalContext().getRequestParameterMap();
String popupState = getHiddenFieldName(facesContext, component);
String showPopup = (String) requestParameterMap.get(popupState);
SelectInputDate dateSelect = (SelectInputDate) component;
if (log.isDebugEnabled()) {
log.debug("selectDate::showPopup" + showPopup);
log.debug("#################################");
}
if (showPopup != null) {
if (showPopup.equalsIgnoreCase("true")) {
dateSelect.setShowPopup(true);
} else {
dateSelect.setShowPopup(false);
}
}
if (log.isDebugEnabled()) {
log.debug("decodeUIInput::");
log.debug("#################################");
}
String clientId = component.getClientId(facesContext);
String inputDateTextId = clientId + SelectInputDate.CALENDAR_INPUTTEXT;
if (requestParameterMap.containsKey(inputDateTextId)) {
String inputDateButtonId = component.getClientId(facesContext) +
CALENDAR_BUTTON;
((BridgeFacesContext)facesContext).setFocusId(inputDateButtonId);
}
CustomComponentUtils.decodeUIInput(facesContext, component, clientId+CALENDAR_CLICK);
// not a navigation event
dateSelect.setNavEvent(false);
}
private void decodeInputText(FacesContext facesContext,
UIComponent component) {
Map requestParameterMap =
facesContext.getExternalContext().getRequestParameterMap();
String popupState = getHiddenFieldName(facesContext, component);
String showPopup = (String) requestParameterMap.get(popupState);
SelectInputDate dateSelect = (SelectInputDate) component;
String clientId = dateSelect.getClientId(facesContext);
//System.out.println("SIDR.decodeInputText() clientId: " + clientId);
Object linkId = getLinkId(facesContext, component);
Object clickedLink = requestParameterMap.get(linkId);
String inputTextDateId = clientId + SelectInputDate.CALENDAR_INPUTTEXT;
//System.out.println("SIDR.decodeInputText() inputTextDateId: " + inputTextDateId);
// inputtext is only available in popup mode
if (requestParameterMap.containsKey(inputTextDateId)) {
if (log.isDebugEnabled()) {
log.debug("decoding InputText EnterKey::");
log.debug("###################################");
}
if (showPopup != null) {
if (checkLink((String) clickedLink, clientId) != IS_NOT) {
if (showPopup.equalsIgnoreCase("true")) {
//System.out.println("SIDR.decodeInputText() setShowPopup( true )");
dateSelect.setShowPopup(true);
} else {
//System.out.println("SIDR.decodeInputText() setShowPopup( false )");
dateSelect.setShowPopup(false);
}
}
}
Object inputTextDate = requestParameterMap.get(inputTextDateId);
//System.out.println("SIDR.decodeInputText() inputTextDate: " + inputTextDate);
if (inputTextDate == null) {
dateSelect.setSubmittedValue(null);
}
else if (String.valueOf(inputTextDate).trim().length() == 0) {
dateSelect.setSubmittedValue("");
}
else {
dateSelect.setSubmittedValue(inputTextDate);
}
}
}
/* (non-Javadoc)
* @see com.icesoft.faces.renderkit.dom_html_basic.DomBasicInputRenderer#getConvertedValue(javax.faces.context.FacesContext, javax.faces.component.UIComponent, java.lang.Object)
*/
public Object getConvertedValue(FacesContext facesContext,
UIComponent uiComponent,
Object submittedValue)
throws ConverterException {
validateParameters(facesContext, uiComponent, SelectInputDate.class);
Converter converter = ((SelectInputDate)uiComponent).resolveDateTimeConverter(facesContext);
if (!(submittedValue == null || submittedValue instanceof String)) {
throw new IllegalArgumentException(
"Submitted value of type String expected");
}
Object o = converter.getAsObject(facesContext, uiComponent,
(String) submittedValue);
return o;
}
}