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 = " " + 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\"> ");
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(" <a href=\"" + UrlRewriter.doRewrite(daily.getPermalink()) + "\">" + formattedNumber + "</a> ");
154 } else {
155 out.write(" " + formattedNumber + " ");
156 }
157 } else {
158 if (daily.hasBlogEntries()) {
159 out.write("<td class=\"calendarDayWithEntries\">");
160 out.write(" <a href=\"" + UrlRewriter.doRewrite(daily.getPermalink()) + "\">" + formattedNumber + "</a> ");
161 } else {
162 out.write("<td class=\"calendarDay\">");
163 out.write(" " + formattedNumber + " ");
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(" | ");
191 out.write("<a href=\"" + UrlRewriter.doRewrite(today.getPermalink()) + "\">" + todayText + "</a>");
192 out.write(" | ");
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 |