calendartag.java

### File Source: calendartag.java

             /*
        P/P   *  Method: net.sourceforge.pebble.web.tagext.CalendarTag__static_init
              */
         1  /*
         2   * Copyright (c) 2003-2006, Simon Brown
         3   * All rights reserved.
         4   *
         5   * Redistribution and use in source and binary forms, with or without
         6   * modification, are permitted provided that the following conditions are met:
         7   *
         8   *   - Redistributions of source code must retain the above copyright
         9   *     notice, this list of conditions and the following disclaimer.
        10   *
        11   *   - Redistributions in binary form must reproduce the above copyright
        12   *     notice, this list of conditions and the following disclaimer in
        13   *     the documentation and/or other materials provided with the
        14   *     distribution.
        15   *
        16   *   - Neither the name of Pebble nor the names of its contributors may
        17   *     be used to endorse or promote products derived from this software
        18   *     without specific prior written permission.
        19   *
        20   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
        21   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        22   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        23   * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
        24   * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
        25   * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
        26   * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
        27   * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
        28   * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        29   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
        30   * POSSIBILITY OF SUCH DAMAGE.
        31   */
        32  package net.sourceforge.pebble.web.tagext;
        33
        34  import java.io.IOException;
        35  import java.text.DateFormatSymbols;
        36  import java.text.NumberFormat;
        37  import java.text.SimpleDateFormat;
        38  import java.util.ArrayList;
        39  import java.util.Calendar;
        40  import java.util.Iterator;
        41  import java.util.List;
        42
             /*
        P/P   *  Method: void net.sourceforge.pebble.web.tagext.CalendarTag()
              */
        43  import javax.servlet.http.HttpServletRequest;
        44  import javax.servlet.jsp.JspException;
        45  import javax.servlet.jsp.JspTagException;
        46  import javax.servlet.jsp.JspWriter;
        47  import javax.servlet.jsp.tagext.TagSupport;
        48
        49  import net.sourceforge.pebble.Constants;
        50  import net.sourceforge.pebble.domain.Blog;
        51  import net.sourceforge.pebble.domain.Day;
        52  import net.sourceforge.pebble.domain.Month;
        53  import net.sourceforge.pebble.util.I18n;
        54  import net.sourceforge.pebble.util.UrlRewriter;
        55
        56  /**
        57   * A custom tag that outputs a calendar control.
        58   *
        59   * @author    Simon Brown
        60   */
        61  public class CalendarTag extends TagSupport {
        62
        63    /**
        64     * Implementation from the Tag interface - this is called when the opening tag
        65     * is encountered.
        66     *
        67     * @return  an integer specifying what to do afterwards
        68     * @throws  JspException    if something goes wrong
        69     */
               /*
        P/P     *  Method: int doStartTag()
                *
                *  Preconditions:
                *    net/sourceforge/pebble/util/UrlRewriter.x != null
                *    this.pageContext != null
                *
                *  Presumptions:
                *    days.length@118 >= 2
                *    java.util.Calendar:getFirstDayOfWeek(...)@114 < days.length@118
                *    java.text.DateFormatSymbols:getShortWeekdays(...)@118 != null
                *    java.text.NumberFormat:format(...)@136 != null
                *    java.text.NumberFormat:getIntegerInstance(...)@89 != null
                *    ...
                *
                *  Postconditions:
                *    return_value == 0
                *
                *  Test Vectors:
                *    java.lang.String:length(...)@137: {0, 2..232-1}, {1}
                *    java.util.Date:after(...)@195: {1}, {0}
                *    java.util.Iterator:hasNext(...)@132: {1}, {0}
                *    javax.servlet.http.HttpServletRequest:getAttribute(...)@74: Inverse{null}, Addr_Set{null}
                *    net.sourceforge.pebble.domain.Day:hasBlogEntries(...)@152: {0}, {1}
                *    net.sourceforge.pebble.domain.Day:hasBlogEntries(...)@158: {0}, {1}
                *    net.sourceforge.pebble.domain.Month:before(...)@100: {0}, {1}
                *    net.sourceforge.pebble.domain.Month:before(...)@183: {0}, {1}
                *    net.sourceforge.pebble.domain.Month:before(...)@195: {0}, {1}
                */
        70    public int doStartTag() throws JspException {
        71
        72      HttpServletRequest request = (HttpServletRequest)pageContext.getRequest();
        73      Blog blog = (Blog)request.getAttribute(Constants.BLOG_KEY);
        74      Month month = (Month)request.getAttribute(Constants.MONTHLY_BLOG);
        75      Day today = blog.getBlogForToday();
        76      Calendar now = blog.getCalendar();
        77
        78      if (month == null) {
        79        month = today.getMonth();
        80      }
        81
        82      Calendar firstDayOfMonth = blog.getCalendar();
        83      firstDayOfMonth.setTime(month.getBlogForDay(1).getDate());
        84
        85      SimpleDateFormat monthAndYearFormatter = new SimpleDateFormat("MMMM yyyy", blog.getLocale());
        86      monthAndYearFormatter.setTimeZone(blog.getTimeZone());
        87      SimpleDateFormat monthFormatter = new SimpleDateFormat("MMM", blog.getLocale());
        88      monthFormatter.setTimeZone(blog.getTimeZone());
        89      NumberFormat numberFormatter = NumberFormat.getIntegerInstance(blog.getLocale());
        90
        91      Month firstMonth = blog.getBlogForFirstMonth();
        92
        93      try {
        94        JspWriter out = pageContext.getOut();
        95
        96        out.write("<div class=\"calendar\">");
        97        out.write("<table width=\"100%\">");
        98        out.write("<tr>");
        99        out.write("<td colspan=\"7\" align=\"center\">");
       100        if (month.before(firstMonth)) {
       101          out.write("<b>");
       102          out.write(monthAndYearFormatter.format(month.getDate()));
       103          out.write("</b>");
       104        } else {
       105          out.write("<b><a href=\"");
       106          out.write(UrlRewriter.doRewrite(month.getPermalink()));
       107          out.write("\">");
       108          out.write(monthAndYearFormatter.format(month.getDate()));
       109          out.write("</a></b>");
       110        }
       111        out.write("</td>");
       112        out.write("</tr>");
       113
       114        int firstDayOfWeek = now.getFirstDayOfWeek();
       115
       116        // write out the calendar header
       117        DateFormatSymbols symbols = new DateFormatSymbols(blog.getLocale());
       118        String[] days = symbols.getShortWeekdays();
       119        out.write("<tr>");
       120        for (int i = firstDayOfWeek; i <= 7; i++) {
    +  121          out.write("<td class=\"calendarDayHeader\" width=\"14%\">" + days[i] + "</td>");
       122        }
       123        for (int i = 1; i < firstDayOfWeek; i++) {
       124          out.write("<td class=\"calendarDayHeader\">" + days[i] + "</td>");
       125        }
       126        out.write("</tr>");
       127
       128        // write out the body of the calendar
       129        Iterator it = getDatesForCompleteWeeks(blog, month).iterator();
       130        Calendar cal;
       131        int count = 0;
       132        while (it.hasNext()) {
       133          cal = (Calendar)it.next();
       134          Day daily = blog.getBlogForDay(cal.getTime());
       135
       136          String formattedNumber = numberFormatter.format(cal.get(Calendar.DAY_OF_MONTH));
       137          if (formattedNumber.length() == 1) {
       138            formattedNumber = "&nbsp;" + formattedNumber;
       139          }
       140
       141          if (count % 7 == 0) {
       142            out.write("<tr>");
       143          }
       144
       145          // output padding if the date to display isn't in the month
       146          if (cal.get(Calendar.MONTH) != firstDayOfMonth.get(Calendar.MONTH)) {
       147            out.write("<td class=\"calendarDay\">&nbsp;");
       148          } else if (now.get(Calendar.YEAR) == cal.get(Calendar.YEAR) &&
       149            now.get(Calendar.MONTH) == cal.get(Calendar.MONTH) &&
       150            now.get(Calendar.DAY_OF_MONTH) == cal.get(Calendar.DAY_OF_MONTH)) {
       151            out.write("<td class=\"calendarToday\">");
       152            if (daily.hasBlogEntries()) {
       153              out.write("&nbsp;<a href=\"" + UrlRewriter.doRewrite(daily.getPermalink()) + "\">" + formattedNumber + "</a>&nbsp;");
       154            } else {
       155              out.write("&nbsp;" + formattedNumber + "&nbsp;");
       156            }
       157          } else {
       158            if (daily.hasBlogEntries()) {
       159              out.write("<td class=\"calendarDayWithEntries\">");
       160              out.write("&nbsp;<a href=\"" + UrlRewriter.doRewrite(daily.getPermalink()) + "\">" + formattedNumber + "</a>&nbsp;");
       161            } else {
       162              out.write("<td class=\"calendarDay\">");
       163              out.write("&nbsp;" + formattedNumber + "&nbsp;");
       164            }
       165          }
       166          out.write("</td>");
       167
       168          if (count % 7 == 6) {
       169            out.write("</tr>");
       170          }
       171
    +  172          count++;
       173        }
       174
       175        // write out the footer of the calendar
       176        Month previous = month.getPreviousMonth();
       177        Month next = month.getNextMonth();
       178
       179        out.write("<tr>");
       180        out.write("<td colspan=\"7\" align=\"center\">");
       181
       182        // only display the previous month link if there are blog entries
       183        if (previous.before(firstMonth)) {
       184          out.write(monthFormatter.format(previous.getDate()));
       185        } else {
       186          out.write("<a href=\"" + UrlRewriter.doRewrite(previous.getPermalink()) + "\">" + monthFormatter.format(previous.getDate()) + "</a>");
       187        }
       188
       189        String todayText = I18n.getMessage(blog, "common.today");
       190        out.write("&nbsp; | &nbsp;");
       191        out.write("<a href=\"" + UrlRewriter.doRewrite(today.getPermalink()) + "\">" + todayText + "</a>");
       192        out.write("&nbsp; | &nbsp;");
       193
       194        // only display the next month date if it's not in the future
       195        if (next.getDate().after(now.getTime()) || next.before(firstMonth)) {
       196          out.write(monthFormatter.format(next.getDate()));
       197        } else {
       198          out.write("<a href=\"" + UrlRewriter.doRewrite(next.getPermalink()) + "\">" + monthFormatter.format(next.getDate()) + "</a>");
       199        }
       200        out.write("</td>");
       201        out.write("</tr>");
       202
       203        out.write("</table>");
       204        out.write("</div>");
       205      } catch (IOException ioe) {
       206        throw new JspTagException(ioe.getMessage());
       207      }
       208
       209      return SKIP_BODY;
       210    }
       211
       212    /**
       213     * Gets a list of dates that should be displayed for the given month. This
       214     * method adds dates either side of the month, padding the list so that it
       215     * contains a number of complete weeks. For example, if the first day of the
       216     * month for the blog's locale is Monday and the given month starts on a
       217     * Tuesday, this method will add in that previous Monday to present
       218     * back a complete week. The same happens for the end of the month. This
       219     * makes rendering easier since we just have a 7xN grid.
       220     *
       221     * @param blog    a Blog instance
       222     * @param month   the month
       223     * @return  a List of Calendar instances
       224     */
               /*
        P/P     *  Method: List getDatesForCompleteWeeks(Blog, Month)
                *
                *  Preconditions:
                *    blog != null
                *    month != null
                *
                *  Presumptions:
                *    net.sourceforge.pebble.domain.Blog:getCalendar(...)@227 != null
                *    net.sourceforge.pebble.domain.Blog:getCalendar(...)@229 != null
                *    net.sourceforge.pebble.domain.Month:getBlogForDay(...)@228 != null
                *    net.sourceforge.pebble.domain.Month:getBlogForDay(...)@230 != null
                *    net.sourceforge.pebble.domain.Month:getLastDayInMonth(...)@234 <= 232-2
                *
                *  Postconditions:
                *    return_value == &new ArrayList(getDatesForCompleteWeeks#1)
                *    new ArrayList(getDatesForCompleteWeeks#1) num objects == 1
                */
       225    private List getDatesForCompleteWeeks(Blog blog, Month month) {
       226      List dates = new ArrayList();
       227      Calendar start = blog.getCalendar();
       228      start.setTime(month.getBlogForDay(1).getDate());
       229      Calendar end = blog.getCalendar();
       230      end.setTime(month.getBlogForDay(month.getLastDayInMonth()).getDate());
       231      Calendar cal;
       232
       233      // put all days in month into a list
       234      for (int i = 1; i <= month.getLastDayInMonth(); i++) {
       235        cal = (Calendar)start.clone();
       236        cal.set(Calendar.DAY_OF_MONTH, i);
       237        dates.add(cal);
       238      }
       239
       240      // pad out before the start of the month, until the first day of the week
       241      cal = (Calendar)start.clone();
       242      while (cal.get(Calendar.DAY_OF_WEEK) != cal.getFirstDayOfWeek()) {
       243        cal.add(Calendar.DATE, -1);
       244        dates.add(0, cal.clone());
       245      }
       246
       247      // pad out after month, until the last day of the week
       248      cal = (Calendar)end.clone();
       249      cal.add(Calendar.DATE, 1);
       250      while (cal.get(Calendar.DAY_OF_WEEK) != cal.getFirstDayOfWeek()) {
       251        dates.add(cal.clone());
       252        cal.add(Calendar.DATE, 1);
       253      }
       254
       255      return dates;
       256    }
       257
       258  }

SofCheck Inspector Build Version : 2.22510

calendartag.java | 2010-Jun-25 19:40:32
calendartag.class | 2010-Jul-19 20:23:38