in trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/renderkit/core/xhtml/ChooseDateRenderer.java [101:500]
protected final void encodeAll(
FacesContext context,
RenderingContext rc,
UIComponent component,
FacesBean bean
) throws IOException
{
// Currently, we require scripting to render anything
if (!supportsScripting(rc))
return;
if (canSkipRendering(context, rc, component))
return;
// If we are running in inline mode, make sure that we are
// in an environment that supports partial page rendering.
// If not, render nothing - the user will need to use the
// secondary window to select a date.
boolean isInline = isInline(component, bean);
if (isInline && !isInlineSupported(rc))
return;
// TRINIDAD-1349: The client converter assumes a fixed timezone offset
// between the server and itself. It calculates that by passing the
// server's timezone offset at the current date-time, as _uixLocaleTZ.
// However, if we are rendering a month in which daylight savings occurs in
// the application timezone, the offset value may be different. In that case
// pass the new offset value for the client to use.
TimeZone tz = rc.getLocaleContext().getTimeZone();
// TRINIDAD-1419: chooseDate golden files should stay the same even if
// the server runs in different timezones.
long currTimeMillis = 0;
Object currTimeValue = bean.getProperty (_currTimeKey);
if (currTimeValue != null)
currTimeMillis = ((Date) currTimeValue).getTime();
else
currTimeMillis = System.currentTimeMillis();
int baseTZOffsetMinutes = tz.getOffset(currTimeMillis/(1000*60));
boolean isDesktop = isDesktop(rc);
ResponseWriter writer = context.getResponseWriter();
writer.startElement("table", component);
renderId(context, component);
renderAllAttributes(context, rc, component, bean);
if (isDesktop)
OutputUtils.renderLayoutTableAttributes(context, rc, "0", null);
else
OutputUtils.renderLayoutTableAttributes(context, rc, "0", "100%");
// Get the styles that we'll use to render the calendar
CalendarStyles styles = _getCalendarStyles(isInline);
// get the calendar of the minimum displayable time
long minTime = _getMinTime(rc, bean);
// get the calendar of the maximum displayable time
long maxTime = _getMaxTime(rc, bean);
// get the currently selected Time
long selectedTime = _getSelectedTime(rc, bean, minTime, maxTime);
// get the id
String id = getClientId(context, component);
// get the destination for the date links
String destString;
if (isInline)
destString = GenericEntry.getGenericEntryURL(
context,
GenericEntry.INLINE_DATE_PICKER_ENTRY);
else
destString = getDestination(component, bean);
// get the calendar of the currently displayed time
Calendar displayedCalendar = _getDisplayedCalendar(rc,
bean,
minTime,
maxTime,
selectedTime);
int firstDOM = _getActualMinimumDayOfMonth(displayedCalendar);
int lastDOM = _getActualMaximumDayOfMonth(displayedCalendar);
// determine the the starting times and ending times of the first and
// last days of the month
// Create a copy of the calendar so we don't hammer the current values
Calendar calcCal = (Calendar) displayedCalendar.clone();
// First is easy
calcCal.set(Calendar.DAY_OF_MONTH, firstDOM);
long firstDOMTime = calcCal.getTimeInMillis();
// Last not just the last day of this month, it's the first day of next
// month minus a millisecond.
calcCal.set(Calendar.DAY_OF_MONTH, lastDOM);
calcCal.add(Calendar.DATE, 1);
long lastDOMTime = calcCal.getTimeInMillis() - 1;
DateFormatSymbols dateSymbols = _getDateFormatSymbols(rc);
int firstDOW = displayedCalendar.getMinimum(Calendar.DAY_OF_WEEK);
int lastDOW = displayedCalendar.getMaximum(Calendar.DAY_OF_WEEK);
int dowCount = lastDOW - firstDOW + 1;
//
// Write the month and year drop downs
//
// If we're running in inline mode, make sure we have
// access to the necessary scripts
if (isInline)
XhtmlUtils.addLib(context, rc, "_calsd()");
// make sure that the js lib is added
XhtmlUtils.addLib(context, rc, "_updateCal()");
String baseNavURL = _createNavURL(rc,
destString,
minTime,
maxTime,
selectedTime,
id);
writer.startElement("tr", null);
// render the previous button
_renderNextPrev(context,
rc,
component,
bean,
true,
minTime,
firstDOMTime,
baseNavURL,
isInline);
writer.startElement("td", null);
writer.writeAttribute("colspan", IntegerUtils.getString(dowCount - 2), null);
renderStyleClass(context, rc, styles.TITLE_STYLE);
// don't wrap the month and year controls
writer.writeAttribute("nowrap", Boolean.TRUE, null);
_renderMonthAndYear(context,
rc,
minTime,
maxTime,
displayedCalendar,
dateSymbols,
baseNavURL,
id,
isInline);
writer.endElement("td");
// render the next button
_renderNextPrev(context,
rc,
component,
bean,
false,
maxTime,
lastDOMTime,
baseNavURL,
isInline);
writer.endElement("tr");
// Place the rest of the calendar content within its own
// table, so that we can style the calendar's border
writer.startElement("tr", null);
writer.startElement("td", null);
writer.writeAttribute("colspan", IntegerUtils.getString(dowCount), null);
writer.startElement("table", null);
//fix for bug 4410632: added summary attribute
OutputUtils.renderDataTableAttributes(context,
rc,
"0", "0", "0", "100%",
rc.getTranslatedString("af_chooseDate.SUMMARY"));
renderStyleClass(context, rc, styles.CONTENT_STYLE);
//
// Write the day of the week headers
//
writer.startElement("tr", null);
renderStyleClass(context, rc, styles.HEADER_STYLE);
String[] shortWeekdays;
// Bug 2388968: Java's "short" weekdays in Arabic are single
// letters, which we're told are inadequate. Output entire
// names instead.
if ("ar".equals(rc.getLocaleContext().getFormattingLocale().getLanguage()))
shortWeekdays = dateSymbols.getWeekdays();
else
shortWeekdays = dateSymbols.getShortWeekdays();
for (int i = firstDOW; i <= lastDOW; i++)
{
writer.startElement("th", null);
writer.writeAttribute("scope", "col", null);
writer.writeText(shortWeekdays[i], null);
writer.endElement("th");
}
writer.endElement("tr");
displayedCalendar.set(Calendar.DAY_OF_MONTH, firstDOM);
int dow = displayedCalendar.get(Calendar.DAY_OF_WEEK);
//
// Output the days in the month
//
writer.startElement("tr", null);
//
// output the days from the previous month in the first week
//
int firstDOWInMonth = firstDOW - dow;
if (firstDOWInMonth < 0)
{
// move to the previous month
displayedCalendar.add(Calendar.MONTH, -1);
// get the count of the last day of the the previous month
int prevLastDOM = _getActualMaximumDayOfMonth(displayedCalendar) -
_getActualMinimumDayOfMonth(displayedCalendar) + 1;
int firstPrevLastDOM = prevLastDOM + firstDOWInMonth + 1;
for (int i = firstPrevLastDOM; i <= prevLastDOM; i++)
{
writer.startElement("td", null);
// Hmm... the font for disabled days in inline calendars
// is way too big - unless we render the disabled style class.
if (isInline)
{
renderStyleClass(context, rc, styles.DISABLED_STYLE);
}
writer.writeText(String.valueOf(i), null);
writer.endElement("td");
}
// move back to the current month
displayedCalendar.add(Calendar.MONTH, 1);
}
int currDOM = firstDOM;
long currTime = firstDOMTime;
displayedCalendar.add(Calendar.DAY_OF_MONTH, 1);
long nextTime = displayedCalendar.getTimeInMillis();
int currLastDOW = firstDOWInMonth + dowCount;
String[] keysAndValues = new String[]{
XhtmlConstants.VALUE_PARAM,
null, // placeholder
XhtmlConstants.EVENT_PARAM,
XhtmlConstants.DATE_EVENT,
XhtmlConstants.TYPE_PARAM,
XhtmlConstants.TYPE_POST,
XhtmlConstants.SOURCE_PARAM,
id};
//
// output the days in this month
//
do
{
for (; (currDOM <= currLastDOW) && (currDOM <= lastDOM); currDOM++)
{
// only days between the minimum and maximum times can be
// selected
boolean enabledDay = (currTime >= minTime) && (currTime <= maxTime);
writer.startElement("td", null);
if (isInline && !enabledDay)
{
renderStyleClass(context, rc, styles.DISABLED_STYLE);
}
boolean selectedDay = false;
if (enabledDay)
{
selectedDay = (selectedTime >= currTime ) &&
(selectedTime < nextTime);
}
if ( enabledDay)
{
//
// even though the selected day doesn't show a link,
// a link is generated to handle the case where the
// user wants to select todays date, but hasn't supplied
// a date in the date field. (see bug #1482511)
//
writer.startElement("a", null);
renderSelectDayAttributes(rc,
context,
keysAndValues,
id,
currTime,
baseTZOffsetMinutes,
isInline,
isDesktop,
destString);
}
if (selectedDay)
{
writer.startElement("span", null);
renderStyleClass(context, rc, styles.SELECTED_STYLE);
}
writer.writeText(String.valueOf(currDOM), null);
if (selectedDay )
{
writer.endElement("span");
}
if (enabledDay)
{
writer.endElement("a");
}
writer.endElement("td");
// move to the next day in time
currTime = nextTime;
displayedCalendar.add(Calendar.DAY_OF_MONTH, 1);
nextTime = displayedCalendar.getTimeInMillis();
}
if (currDOM <= lastDOM)
{
// end the current week row
writer.endElement("tr");
// start next week's row
writer.startElement("tr", null);
currLastDOW += dowCount;
}
else
{
break;
}
} while (true);
// Reset the calendar
displayedCalendar.set(Calendar.DAY_OF_MONTH, firstDOM);
//
// output the days from the next month in the last week
//
int lastDOWInMonth = currLastDOW - currDOM + 1;
if (lastDOWInMonth > 0)
{
// move to the next month
displayedCalendar.add(Calendar.MONTH, 1);
// get the count of the last day of the the previous month
int nextFirstDOM = _getActualMinimumDayOfMonth(displayedCalendar);
int nextLastDOM = nextFirstDOM + lastDOWInMonth - 1;
for (int i = nextFirstDOM; i <= nextLastDOM; i++)
{
writer.startElement("td", null);
if (isInline)
{
renderStyleClass(context, rc, styles.DISABLED_STYLE);
}
writer.writeText(String.valueOf(i), null);
writer.endElement("td");
}
}
writer.endElement("tr");
writer.endElement("table");
writer.endElement("td");
writer.endElement("tr");
writer.endElement("table");
}