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