Coverage Report - net.sourceforge.pebble.web.tagext.CalendarTag
 
Classes in this File Line Coverage Branch Coverage Complexity
CalendarTag
0%
0/109
0%
0/40
12
 
 1  
 /*
 2  
  * Copyright (c) 2003-2011, 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  
 
 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  0
 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  
    */
 70  
   public int doStartTag() throws JspException {
 71  
 
 72  0
     HttpServletRequest request = (HttpServletRequest)pageContext.getRequest();
 73  0
     Blog blog = (Blog)request.getAttribute(Constants.BLOG_KEY);
 74  0
     Month month = (Month)request.getAttribute(Constants.MONTHLY_BLOG);
 75  0
     Day today = blog.getBlogForToday();
 76  0
     Calendar now = blog.getCalendar();
 77  
 
 78  0
     if (month == null) {
 79  0
       month = today.getMonth();
 80  
     }
 81  
 
 82  0
     Calendar firstDayOfMonth = blog.getCalendar();
 83  0
     firstDayOfMonth.setTime(month.getBlogForDay(1).getDate());
 84  
 
 85  0
     SimpleDateFormat monthAndYearFormatter = new SimpleDateFormat("MMMM yyyy", blog.getLocale());
 86  0
     monthAndYearFormatter.setTimeZone(blog.getTimeZone());
 87  0
     SimpleDateFormat monthFormatter = new SimpleDateFormat("MMM", blog.getLocale());
 88  0
     monthFormatter.setTimeZone(blog.getTimeZone());
 89  0
     NumberFormat numberFormatter = NumberFormat.getIntegerInstance(blog.getLocale());
 90  
 
 91  0
     Month firstMonth = blog.getBlogForFirstMonth();
 92  
 
 93  
     try {
 94  0
       JspWriter out = pageContext.getOut();
 95  
 
 96  0
       out.write("<div class=\"calendar\">");
 97  0
       out.write("<table width=\"100%\">");
 98  0
       out.write("<tr>");
 99  0
       out.write("<td colspan=\"7\" align=\"center\">");
 100  0
       if (month.before(firstMonth)) {
 101  0
         out.write("<b>");
 102  0
         out.write(monthAndYearFormatter.format(month.getDate()));
 103  0
         out.write("</b>");
 104  
       } else {
 105  0
         out.write("<b><a href=\"");
 106  0
         out.write(UrlRewriter.doRewrite(month.getPermalink()));
 107  0
         out.write("\">");
 108  0
         out.write(monthAndYearFormatter.format(month.getDate()));
 109  0
         out.write("</a></b>");
 110  
       }
 111  0
       out.write("</td>");
 112  0
       out.write("</tr>");
 113  
 
 114  0
       int firstDayOfWeek = now.getFirstDayOfWeek();
 115  
 
 116  
       // write out the calendar header
 117  0
       DateFormatSymbols symbols = new DateFormatSymbols(blog.getLocale());
 118  0
       String[] days = symbols.getShortWeekdays();
 119  0
       out.write("<tr>");
 120  0
       for (int i = firstDayOfWeek; i <= 7; i++) {
 121  0
         out.write("<td class=\"calendarDayHeader\" width=\"14%\">" + days[i] + "</td>");
 122  
       }
 123  0
       for (int i = 1; i < firstDayOfWeek; i++) {
 124  0
         out.write("<td class=\"calendarDayHeader\">" + days[i] + "</td>");
 125  
       }
 126  0
       out.write("</tr>");
 127  
 
 128  
       // write out the body of the calendar
 129  0
       Iterator it = getDatesForCompleteWeeks(blog, month).iterator();
 130  
       Calendar cal;
 131  0
       int count = 0;
 132  0
       while (it.hasNext()) {
 133  0
         cal = (Calendar)it.next();
 134  0
         Day daily = blog.getBlogForDay(cal.getTime());
 135  
 
 136  0
         String formattedNumber = numberFormatter.format(cal.get(Calendar.DAY_OF_MONTH));
 137  0
         if (formattedNumber.length() == 1) {
 138  0
           formattedNumber = "&nbsp;" + formattedNumber;
 139  
         }
 140  
 
 141  0
         if (count % 7 == 0) {
 142  0
           out.write("<tr>");
 143  
         }
 144  
 
 145  
         // output padding if the date to display isn't in the month
 146  0
         if (cal.get(Calendar.MONTH) != firstDayOfMonth.get(Calendar.MONTH)) {
 147  0
           out.write("<td class=\"calendarDay\">&nbsp;");
 148  0
         } 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  0
           out.write("<td class=\"calendarToday\">");
 152  0
           if (daily.hasBlogEntries()) {
 153  0
             out.write("&nbsp;<a href=\"" + UrlRewriter.doRewrite(daily.getPermalink()) + "\">" + formattedNumber + "</a>&nbsp;");
 154  
           } else {
 155  0
             out.write("&nbsp;" + formattedNumber + "&nbsp;");
 156  
           }
 157  
         } else {
 158  0
           if (daily.hasBlogEntries()) {
 159  0
             out.write("<td class=\"calendarDayWithEntries\">");
 160  0
             out.write("&nbsp;<a href=\"" + UrlRewriter.doRewrite(daily.getPermalink()) + "\">" + formattedNumber + "</a>&nbsp;");
 161  
           } else {
 162  0
             out.write("<td class=\"calendarDay\">");
 163  0
             out.write("&nbsp;" + formattedNumber + "&nbsp;");
 164  
           }
 165  
         }
 166  0
         out.write("</td>");
 167  
 
 168  0
         if (count % 7 == 6) {
 169  0
           out.write("</tr>");
 170  
         }
 171  
 
 172  0
         count++;
 173  0
       }
 174  
 
 175  
       // write out the footer of the calendar
 176  0
       Month previous = month.getPreviousMonth();
 177  0
       Month next = month.getNextMonth();
 178  
 
 179  0
       out.write("<tr>");
 180  0
       out.write("<td colspan=\"7\" align=\"center\">");
 181  
 
 182  
       // only display the previous month link if there are blog entries
 183  0
       if (previous.before(firstMonth)) {
 184  0
         out.write(monthFormatter.format(previous.getDate()));
 185  
       } else {
 186  0
         out.write("<a href=\"" + UrlRewriter.doRewrite(previous.getPermalink()) + "\">" + monthFormatter.format(previous.getDate()) + "</a>");
 187  
       }
 188  
 
 189  0
       String todayText = I18n.getMessage(blog, "common.today");
 190  0
       out.write("&nbsp; | &nbsp;");
 191  0
       out.write("<a href=\"" + UrlRewriter.doRewrite(today.getPermalink()) + "\">" + todayText + "</a>");
 192  0
       out.write("&nbsp; | &nbsp;");
 193  
 
 194  
       // only display the next month date if it's not in the future
 195  0
       if (next.getDate().after(now.getTime()) || next.before(firstMonth)) {
 196  0
         out.write(monthFormatter.format(next.getDate()));
 197  
       } else {
 198  0
         out.write("<a href=\"" + UrlRewriter.doRewrite(next.getPermalink()) + "\">" + monthFormatter.format(next.getDate()) + "</a>");
 199  
       }
 200  0
       out.write("</td>");
 201  0
       out.write("</tr>");
 202  
 
 203  0
       out.write("</table>");
 204  0
       out.write("</div>");
 205  0
     } catch (IOException ioe) {
 206  0
       throw new JspTagException(ioe.getMessage());
 207  0
     }
 208  
 
 209  0
     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  
    */
 225  
   private List getDatesForCompleteWeeks(Blog blog, Month month) {
 226  0
     List dates = new ArrayList();
 227  0
     Calendar start = blog.getCalendar();
 228  0
     start.setTime(month.getBlogForDay(1).getDate());
 229  0
     Calendar end = blog.getCalendar();
 230  0
     end.setTime(month.getBlogForDay(month.getLastDayInMonth()).getDate());
 231  
     Calendar cal;
 232  
 
 233  
     // put all days in month into a list
 234  0
     for (int i = 1; i <= month.getLastDayInMonth(); i++) {
 235  0
       cal = (Calendar)start.clone();
 236  0
       cal.set(Calendar.DAY_OF_MONTH, i);
 237  0
       dates.add(cal);
 238  
     }
 239  
 
 240  
     // pad out before the start of the month, until the first day of the week
 241  0
     cal = (Calendar)start.clone();
 242  0
     while (cal.get(Calendar.DAY_OF_WEEK) != cal.getFirstDayOfWeek()) {
 243  0
       cal.add(Calendar.DATE, -1);
 244  0
       dates.add(0, cal.clone());
 245  
     }
 246  
 
 247  
     // pad out after month, until the last day of the week
 248  0
     cal = (Calendar)end.clone();
 249  0
     cal.add(Calendar.DATE, 1);
 250  0
     while (cal.get(Calendar.DAY_OF_WEEK) != cal.getFirstDayOfWeek()) {
 251  0
       dates.add(cal.clone());
 252  0
       cal.add(Calendar.DATE, 1);
 253  
     }
 254  
 
 255  0
     return dates;
 256  
   }
 257  
 
 258  
 }