protected final void encodeAll()

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");
  }