001: /**********************************************************************************
002: * $URL: https://source.sakaiproject.org/svn/calendar/tags/sakai_2-4-1/calendar-tool/tool/src/java/org/sakaiproject/calendar/tool/CalendarFilter.java $
003: * $Id: CalendarFilter.java 8050 2006-04-20 17:39:55Z ggolden@umich.edu $
004: ***********************************************************************************
005: *
006: * Copyright (c) 2003, 2004, 2005, 2006 The Sakai Foundation.
007: *
008: * Licensed under the Educational Community License, Version 1.0 (the "License");
009: * you may not use this file except in compliance with the License.
010: * You may obtain a copy of the License at
011: *
012: * http://www.opensource.org/licenses/ecl1.php
013: *
014: * Unless required by applicable law or agreed to in writing, software
015: * distributed under the License is distributed on an "AS IS" BASIS,
016: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017: * See the License for the specific language governing permissions and
018: * limitations under the License.
019: *
020: **********************************************************************************/package org.sakaiproject.calendar.tool;
021:
022: import java.text.ParseException;
023: import java.text.SimpleDateFormat;
024: import java.util.Date;
025: import java.util.GregorianCalendar;
026: import java.util.Iterator;
027: import java.util.Vector;
028:
029: import org.sakaiproject.calendar.api.CalendarEvent;
030: import org.sakaiproject.time.api.Time;
031: import org.sakaiproject.time.api.TimeBreakdown;
032: import org.sakaiproject.time.api.TimeRange;
033: import org.sakaiproject.time.cover.TimeService;
034: import org.sakaiproject.util.ResourceLoader;
035:
036: /**
037: * This class provides filtering (currently only by date) for use
038: * in the CalendarAction list view.
039: */
040: class CalendarFilter {
041:
042: /** Resource bundle using current language locale */
043: private static ResourceLoader rb = new ResourceLoader("calendar");
044:
045: /**
046: * Used to parse date entered by the user. This format should really be internationalized.
047: */
048: public final static String LIST_VIEW_DATE_FORMAT_PARSE = "MM/dd/yy";
049:
050: /**
051: * This is the same format, but in a form that is used to suggest the correct format to enter dates.
052: */
053: public final static String LIST_VIEW_DATE_FORMAT_DISPLAY = "mm/dd/yy";
054:
055: /**
056: * Number of years that we want to cover in the list view.
057: */
058: private static final int LIST_VIEW_YEAR_RANGE = 8;
059:
060: /**
061: * Format object to go along with the above format string.
062: */
063: private final static SimpleDateFormat LIST_VIEW_DATE_FORMAT = new SimpleDateFormat(
064: LIST_VIEW_DATE_FORMAT_PARSE);
065:
066: /**
067: * The end year is the current date plus half the range.
068: */
069: public static final int LIST_VIEW_ENDING_YEAR = TimeService
070: .newTime().breakdownLocal().getYear()
071: + LIST_VIEW_YEAR_RANGE / 2;
072:
073: /**
074: * The start year is the current date minus half the range.
075: */
076: public static final int LIST_VIEW_STARTING_YEAR = TimeService
077: .newTime().breakdownLocal().getYear()
078: - LIST_VIEW_YEAR_RANGE / 2;
079:
080: /** Mode to show the default range of dates */
081: public final static String SHOW_ALL_RANGE = "SHOW_ALL";
082:
083: /** Mode to show ranges of dates specified by the user */
084: public final static String SHOW_CUSTOM_RANGE = "SHOW_CUSTOM_RANGE";
085:
086: /** Mode to show only events for today. */
087: public final static String SHOW_DAY = "SHOW_DAY";
088:
089: /** Mode to show only events for this month. */
090: public final static String SHOW_MONTH = "SHOW_MONTH";
091:
092: /** Mode to show only events for this week. */
093: public final static String SHOW_WEEK = "SHOW_WEEK";
094:
095: /** Mode to only show events for this year. */
096: public final static String SHOW_YEAR = "SHOW_YEAR";
097:
098: private Time startingListViewDate;
099: private Time endingListViewDate;
100:
101: private int LIST_VIEW_ENDING_DAY = 31;
102: private int LIST_VIEW_ENDING_MONTH = 12;
103:
104: // Default start/end dates for the list view.
105: private int LIST_VIEW_STARTING_DAY = 1;
106: private int LIST_VIEW_STARTING_MONTH = 1;
107: private boolean listViewDatesCustomized = false;
108:
109: // Default to showing all events within the default range.
110: private String listViewFilterMode = SHOW_ALL_RANGE;
111:
112: /**
113: * Filter events based on the custom date range
114: */
115: public Iterator filterEvents(Iterator it) {
116: // Don't filter if none of our filters are enabled.
117: if (SHOW_ALL_RANGE.equals(getListViewFilterMode())) {
118: return it;
119: } else {
120: // pull the range of events from vector
121: Vector events = new Vector();
122: TimeRange filterTimeRange = this .getListViewTimeRange();
123:
124: while (it.hasNext()) {
125: CalendarEvent test = (CalendarEvent) it.next();
126:
127: if (filterTimeRange.overlaps(test.getRange())) {
128: events.add(test);
129: }
130: }
131:
132: return events.iterator();
133: }
134: }
135:
136: /**
137: * Get a string representing the end date.
138: */
139: public String getEndingListViewDateString() {
140: return LIST_VIEW_DATE_FORMAT.format(new Date(endingListViewDate
141: .getTime()));
142: }
143:
144: /**
145: * Get the ending year for the list view.
146: */
147: public int getEndingListViewYear() {
148: GregorianCalendar cal = new GregorianCalendar(TimeService
149: .getLocalTimeZone());
150:
151: cal.setTime(new Date(endingListViewDate.getTime()));
152:
153: return cal.get(GregorianCalendar.YEAR);
154: }
155:
156: /**
157: * Get the list view ending date as a Time object.
158: */
159: public Time getListViewEndingTime() {
160: return endingListViewDate;
161: }
162:
163: public String getListViewFilterMode() {
164: return listViewFilterMode;
165: }
166:
167: /**
168: * Get the list view starting date as a Time object.
169: */
170: public Time getListViewStartingTime() {
171: return startingListViewDate;
172: }
173:
174: /**
175: * Get a TimeRange object for the list view start/end dates.
176: */
177: public TimeRange getListViewTimeRange() {
178: return TimeService.newTimeRange(this .startingListViewDate,
179: this .endingListViewDate);
180: }
181:
182: /**
183: * Get a string representing the start date.
184: */
185: public String getStartingListViewDateString() {
186: return LIST_VIEW_DATE_FORMAT.format(new Date(
187: startingListViewDate.getTime()));
188: }
189:
190: /**
191: * Get the starting year for the list view.
192: */
193: public int getStartingListViewYear() {
194: GregorianCalendar cal = new GregorianCalendar(TimeService
195: .getLocalTimeZone());
196:
197: cal.setTime(new Date(startingListViewDate.getTime()));
198:
199: return cal.get(GregorianCalendar.YEAR);
200: }
201:
202: /**
203: * Returns true if this starting/ending for the list view have been customized.
204: */
205: public boolean isCustomListViewDates() {
206: return listViewDatesCustomized;
207: }
208:
209: /**
210: * Reset the start/end dates to their default values.
211: */
212: public void setListViewDateRangeToDefault() {
213: setStartAndEndListViewDates(LIST_VIEW_STARTING_YEAR,
214: LIST_VIEW_STARTING_MONTH, LIST_VIEW_STARTING_DAY,
215: LIST_VIEW_ENDING_YEAR, LIST_VIEW_ENDING_MONTH,
216: LIST_VIEW_ENDING_DAY);
217: }
218:
219: public void setListViewFilterMode(String mode) {
220: boolean validMode = true;
221: int startYear = 0, startMonth = 0, startDay = 0, endYear = 0, endMonth = 0, endDay = 0;
222:
223: if (SHOW_ALL_RANGE.equals(mode)) {
224: // Use all the default values.
225: startYear = LIST_VIEW_STARTING_YEAR;
226: endYear = LIST_VIEW_ENDING_YEAR;
227:
228: startMonth = LIST_VIEW_STARTING_MONTH;
229: endMonth = LIST_VIEW_ENDING_MONTH;
230:
231: startDay = LIST_VIEW_STARTING_DAY;
232: endDay = LIST_VIEW_ENDING_DAY;
233: } else if (SHOW_DAY.equals(mode)) {
234: // To show the day, we only use one date for start/end.
235: TimeBreakdown breakDown = TimeService.newTime()
236: .breakdownLocal();
237:
238: startYear = breakDown.getYear();
239: endYear = startYear;
240:
241: startMonth = breakDown.getMonth();
242: endMonth = startMonth;
243:
244: startDay = breakDown.getDay();
245: endDay = startDay;
246: } else if (SHOW_WEEK.equals(mode)) {
247: GregorianCalendar calStart = new GregorianCalendar(
248: TimeService.getLocalTimeZone());
249: GregorianCalendar calEnd = (GregorianCalendar) calStart
250: .clone();
251:
252: // Set the first/last days of the week.
253: calStart.set(GregorianCalendar.DAY_OF_WEEK, 1);
254: calEnd.set(GregorianCalendar.DAY_OF_WEEK, 7);
255:
256: startYear = calStart.get(GregorianCalendar.YEAR);
257: endYear = calEnd.get(GregorianCalendar.YEAR);
258:
259: startMonth = calStart.get(GregorianCalendar.MONTH) + 1;
260: endMonth = calEnd.get(GregorianCalendar.MONTH) + 1;
261:
262: startDay = calStart.get(GregorianCalendar.DAY_OF_MONTH);
263: endDay = calEnd.get(GregorianCalendar.DAY_OF_MONTH);
264: } else if (SHOW_MONTH.equals(mode)) {
265: GregorianCalendar calStart = new GregorianCalendar(
266: TimeService.getLocalTimeZone());
267: GregorianCalendar calEnd = (GregorianCalendar) calStart
268: .clone();
269:
270: // Set the first/last days of the month.
271: calStart.set(GregorianCalendar.DAY_OF_MONTH, 1);
272: calEnd.set(GregorianCalendar.DAY_OF_MONTH, calStart
273: .getMaximum(GregorianCalendar.DAY_OF_MONTH));
274:
275: startYear = calStart.get(GregorianCalendar.YEAR);
276: endYear = calEnd.get(GregorianCalendar.YEAR);
277:
278: startMonth = calStart.get(GregorianCalendar.MONTH) + 1;
279: endMonth = calEnd.get(GregorianCalendar.MONTH) + 1;
280:
281: startDay = calStart.get(GregorianCalendar.DAY_OF_MONTH);
282: endDay = calEnd.get(GregorianCalendar.DAY_OF_MONTH);
283: } else if (SHOW_YEAR.equals(mode)) {
284: TimeBreakdown breakDown = TimeService.newTime()
285: .breakdownLocal();
286:
287: startYear = breakDown.getYear();
288: endYear = startYear;
289:
290: startMonth = 1;
291: endMonth = 12;
292:
293: startDay = 1; // January 1
294: endDay = 31; // December 31st
295: } else if (SHOW_CUSTOM_RANGE.equals(mode)) {
296: TimeBreakdown startBreakdown = startingListViewDate
297: .breakdownLocal();
298: TimeBreakdown endBreakdown = endingListViewDate
299: .breakdownLocal();
300:
301: startYear = startBreakdown.getYear();
302: endYear = endBreakdown.getYear();
303:
304: startMonth = startBreakdown.getMonth();
305: endMonth = endBreakdown.getMonth();
306:
307: startDay = startBreakdown.getDay();
308: endDay = endBreakdown.getDay();
309: } else {
310: validMode = false;
311: }
312:
313: if (validMode) {
314: listViewFilterMode = mode;
315:
316: setStartAndEndListViewDates(startYear, startMonth,
317: startDay, endYear, endMonth, endDay);
318: }
319: }
320:
321: /**
322: * Set the start/end year, month, and day. The time portion of the
323: * starting and ending days is automatically supplied to ensure that
324: * we will get full days of events.
325: */
326: private void setStartAndEndListViewDates(int startYear,
327: int startMonth, int startDay, int endYear, int endMonth,
328: int endDay) {
329: startingListViewDate = TimeService.newTimeLocal(startYear,
330: startMonth, startDay, 0, 0, 0, 0);
331:
332: endingListViewDate = TimeService.newTimeLocal(endYear,
333: endMonth, endDay, 23, 59, 59, 99);
334: }
335:
336: /**
337: * Set the start/end dates from strings. Format an error message and return false if there is a problem.
338: */
339: public boolean setStartAndEndListViewDates(String startingDateStr,
340: String endingDateStr, StringBuffer errorMessage) {
341: Date startDate, endDate;
342:
343: try {
344: startDate = LIST_VIEW_DATE_FORMAT.parse(startingDateStr);
345: endDate = LIST_VIEW_DATE_FORMAT.parse(endingDateStr);
346: } catch (ParseException e) {
347: errorMessage.append(rb.getString("java.alert.invalid"));
348: return false;
349: }
350:
351: // Do a sanity check
352: if (startDate.after(endDate)) {
353: errorMessage.append(rb.getString("java.alert.start"));
354: return false;
355: }
356:
357: // Use Gregorian calendars to pick out the year, month, and day.
358: GregorianCalendar calStart = new GregorianCalendar(TimeService
359: .getLocalTimeZone());
360:
361: GregorianCalendar calEnd = new GregorianCalendar(TimeService
362: .getLocalTimeZone());
363:
364: calStart.setTime(startDate);
365: calEnd.setTime(endDate);
366:
367: startingListViewDate = TimeService.newTimeLocal(calStart
368: .get(GregorianCalendar.YEAR), calStart
369: .get(GregorianCalendar.MONTH) + 1, calStart
370: .get(GregorianCalendar.DAY_OF_MONTH), 0, 0, 0, 0);
371:
372: endingListViewDate = TimeService.newTimeLocal(calEnd
373: .get(GregorianCalendar.YEAR), calEnd
374: .get(GregorianCalendar.MONTH) + 1, calEnd
375: .get(GregorianCalendar.DAY_OF_MONTH), 23, 59, 59, 99);
376:
377: // Set a flag to indicate that we've modified the defaults
378: // and to switch our viewing mode.
379: listViewDatesCustomized = true;
380:
381: listViewFilterMode = SHOW_CUSTOM_RANGE;
382:
383: return true;
384: }
385: }
|