KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > ivata > groupware > business > calendar > struts > IndexAction


1 /*
2  * Copyright (c) 2001 - 2005 ivata limited.
3  * All rights reserved.
4  * -----------------------------------------------------------------------------
5  * ivata groupware may be redistributed under the GNU General Public
6  * License as published by the Free Software Foundation;
7  * version 2 of the License.
8  *
9  * These programs are free software; you can redistribute them and/or
10  * modify them under the terms of the GNU General Public License
11  * as published by the Free Software Foundation; version 2 of the License.
12  *
13  * These programs are distributed in the hope that they will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16  *
17  * See the GNU General Public License in the file LICENSE.txt for more
18  * details.
19  *
20  * If you would like a copy of the GNU General Public License write to
21  *
22  * Free Software Foundation, Inc.
23  * 59 Temple Place - Suite 330
24  * Boston, MA 02111-1307, USA.
25  *
26  *
27  * To arrange commercial support and licensing, contact ivata at
28  * http://www.ivata.com/contact.jsp
29  * -----------------------------------------------------------------------------
30  * $Log: IndexAction.java,v $
31  * Revision 1.3 2005/04/10 18:47:37 colinmacleod
32  * Changed i tag to em and b tag to strong.
33  *
34  * Revision 1.2 2005/04/09 17:19:18 colinmacleod
35  * Changed copyright text to GPL v2 explicitly.
36  *
37  * Revision 1.1.1.1 2005/03/10 17:47:42 colinmacleod
38  * Restructured ivata op around Hibernate/PicoContainer.
39  * Renamed ivata groupware.
40  *
41  * Revision 1.9 2004/12/31 18:27:43 colinmacleod
42  * Added MaskFactory to constructor of MaskAction.
43  *
44  * Revision 1.8 2004/12/23 21:01:27 colinmacleod
45  * Updated Struts to v1.2.4.
46  * Changed base classes to use ivata masks.
47  *
48  * Revision 1.7 2004/11/12 18:19:14 colinmacleod
49  * Change action and form classes to extend MaskAction, MaskForm respectively.
50  *
51  * Revision 1.6 2004/11/12 16:08:11 colinmacleod
52  * Removed dependencies on SSLEXT.
53  * Moved Persistence classes to ivata masks.
54  *
55  * Revision 1.5 2004/11/03 15:31:50 colinmacleod
56  * Change method interfaces to remove log.
57  *
58  * Revision 1.4 2004/07/13 19:42:14 colinmacleod
59  * Moved project to POJOs from EJBs.
60  * Applied PicoContainer to services layer (replacing session EJBs).
61  * Applied Hibernate to persistence layer (replacing entity EJBs).
62  *
63  * Revision 1.3 2004/03/21 21:16:22 colinmacleod
64  * Shortened name to ivata op.
65  *
66  * Revision 1.2 2004/02/01 22:07:29 colinmacleod
67  * Added full names to author tags
68  *
69  * Revision 1.1.1.1 2004/01/27 20:58:22 colinmacleod
70  * Moved ivata openportal to SourceForge..
71  *
72  * Revision 1.4 2003/11/13 16:07:26 jano
73  * commitng everything to CVS
74  * can deploy and application is ruuning, can login into
75  *
76  * Revision 1.3 2003/10/28 13:10:23 jano
77  * commiting calendar,
78  * still fixing compile and building openGroupware project
79  *
80  * Revision 1.2 2003/10/15 13:57:23 colin
81  * fixing for XDoclet
82  *
83  * Revision 1.4 2003/04/03 13:26:35 jano
84  * cosmetic change
85  *
86  * Revision 1.3 2003/03/13 17:08:04 peter
87  * fixed: the sorting is now timeZone aware
88  *
89  * Revision 1.2 2003/02/28 09:36:51 jano
90  * RuntimeException(e) -> IntrnetRuntimeException
91  *
92  * Revision 1.1 2003/02/24 19:09:22 colin
93  * moved to business
94  *
95  * Revision 1.3 2003/02/20 13:04:33 peter
96  * 24H time formats changed to simple ones
97  *
98  * Revision 1.2 2003/02/13 08:45:42 colin
99  * conversion to Struts/popups
100  *
101  * Revision 1.1 2003/02/04 17:50:17 colin
102  * first version in CVS
103  *
104  * Revision 1.1 2003/02/04 17:41:16 colin
105  * first version in CVS
106  *
107  * Revision 1.6 2003/01/30 09:02:19 colin
108  * updates for struts conversion
109  *
110  * Revision 1.5 2003/01/18 20:12:36 colin
111  * fixes and changes to override new MaskAction method
112  *
113  * Revision 1.4 2003/01/10 10:29:46 jano
114  * we need information about user who created group
115  *
116  * Revision 1.3 2003/01/09 10:50:54 jano
117  * I need only one method for finding right for group
118  *
119  * Revision 1.2 2003/01/08 17:16:21 jano
120  * We will use new methods for finding and changing rights for
121  * GROUP of AddressBookRightsBean
122  * -----------------------------------------------------------------------------
123  */

124 package com.ivata.groupware.business.calendar.struts;
125
126 import java.util.Collection JavaDoc;
127 import java.util.GregorianCalendar JavaDoc;
128 import java.util.HashMap JavaDoc;
129 import java.util.Iterator JavaDoc;
130 import java.util.Map JavaDoc;
131 import java.util.TimeZone JavaDoc;
132 import java.util.TreeSet JavaDoc;
133 import java.util.Vector JavaDoc;
134
135 import javax.servlet.http.HttpServletRequest JavaDoc;
136 import javax.servlet.http.HttpServletResponse JavaDoc;
137 import javax.servlet.http.HttpSession JavaDoc;
138
139 import org.apache.struts.action.ActionErrors;
140 import org.apache.struts.action.ActionForm;
141 import org.apache.struts.action.ActionMapping;
142
143 import com.ivata.groupware.admin.security.server.SecuritySession;
144 import com.ivata.groupware.admin.security.user.UserDO;
145 import com.ivata.groupware.admin.setting.Settings;
146 import com.ivata.groupware.admin.setting.SettingsDataTypeException;
147 import com.ivata.groupware.business.calendar.Calendar;
148 import com.ivata.groupware.business.calendar.event.EventDO;
149 import com.ivata.groupware.util.SettingDateFormatter;
150 import com.ivata.mask.MaskFactory;
151 import com.ivata.mask.util.StringHandling;
152 import com.ivata.mask.util.SystemException;
153 import com.ivata.mask.web.format.DateFormatterConstants;
154 import com.ivata.mask.web.struts.MaskAction;
155 import com.ivata.mask.web.struts.MaskAuthenticator;
156
157
158 /**
159  * <p>This action is invoked from the main calendar index, to create
160  * the appropriate view.</p>
161  *
162  * @since 2003-02-02
163  * @author Colin MacLeod
164  * <a HREF='mailto:colin.macleod@ivata.com'>colin.macleod@ivata.com</a>
165  * @version $Revision: 1.3 $
166  *
167  */

168 public class IndexAction extends MaskAction {
169     private Calendar JavaDoc calendar;
170     private SettingDateFormatter dateFormatter;
171     private Settings settings;
172     /**
173      * TODO
174      *
175      * @param calendar
176      * @param settings
177      * @param dateFormatter
178      * @param maskFactory This factory is needed to access the masks and groups
179      * of masks.
180      * @param authenticator used to confirm whether or not the
181      * user should be allowed to continue, in the <code>execute</code> method.
182      */

183     public IndexAction(Calendar JavaDoc calendar, Settings settings, SettingDateFormatter
184             dateFormatter, MaskFactory maskFactory,
185             MaskAuthenticator authenticator) {
186         super(maskFactory, authenticator);
187         this.calendar = calendar;
188         this.settings = settings;
189         this.dateFormatter = dateFormatter;
190     }
191
192     /**
193      * <p>Invoked when the user views a calendar list.</p>
194      *
195      * @param mapping current action mapping from <em>Struts</em> config.
196      * @param log valid logging object to write messages to.
197      * @param errors valid errors object to append errors to. If there are
198      * any errors, the action will return to the input.
199      * @param form optional ActionForm bean for this request (if any)
200      * @param request non-HTTP request we are processing
201      * @param response The non-HTTP response we are creating
202      * @param session returned from the <code>request</code> parameter.
203      * @param userName current user name from session. .
204      * @param settings valid, non-null settings from session.
205      * @exception SystemException if there is any problem which
206      * prevents processing. It will result in the webapp being forwarded
207      * to
208      * the standard error page.
209      * @return this method returns the string used to identify the correct
210      * <em>Struts</em> <code>ActionForward</code> which should follow this
211      * page, or <code>null</code> if it should return to the input.
212      *
213      *
214      */

215     public String JavaDoc execute(final ActionMapping mapping,
216             final ActionErrors errors,
217             final ActionForm form,
218             final HttpServletRequest JavaDoc request,
219             final HttpServletResponse JavaDoc response,
220             final HttpSession JavaDoc session) throws SystemException {
221         SecuritySession securitySession = (SecuritySession) session.getAttribute("securitySession");
222         UserDO user = securitySession.getUser();
223         IndexForm indexForm = (IndexForm) form;
224         TimeZone JavaDoc timeZone;
225         timeZone =
226             TimeZone.getTimeZone(
227                 settings.getStringSetting(
228                     securitySession,
229                     "i18nTimeZone",
230                     user));
231
232         GregorianCalendar JavaDoc day = indexForm.getCurrentDay();
233         day.setTimeZone(timeZone);
234
235         // see if there is a view from before
236
Integer JavaDoc view = indexForm.getView();
237         // request overrides the form
238
Integer JavaDoc requestView = StringHandling.integerValue(request.getParameter("view"));
239         if (requestView != null) {
240             indexForm.setView(view = requestView);
241         }
242
243         // if this is the first trip to the calendar, or if you asked for it
244
// make the current day today
245
if ((view == null)
246                 || (request.getParameter("today") != null)) {
247             day.setTime(new java.util.Date JavaDoc());
248             day.set(GregorianCalendar.HOUR_OF_DAY, 0);
249             day.set(GregorianCalendar.MINUTE, 0);
250             day.set(GregorianCalendar.SECOND, 0);
251             day.set(GregorianCalendar.MILLISECOND, 0);
252
253             // if there is no view parameter, take the current view from the
254
// settings
255
if (view == null) {
256                 try {
257                     indexForm.setView(view = settings.getIntegerSetting(securitySession,
258                         "calendarDefaultView", user));
259                 } catch (SettingsDataTypeException e2) {
260                     throw new SystemException(e2);
261                 }
262             }
263         }
264
265
266         // if someone clicked to day link in week view
267
if (request.getParameter("day") != null) {
268             day.set( GregorianCalendar.DATE,
269                 new Integer JavaDoc(request.getParameter("day")).intValue());
270             day.set( GregorianCalendar.MONTH,
271                 new Integer JavaDoc(request.getParameter("month")).intValue());
272             day.set( GregorianCalendar.YEAR,
273                 new Integer JavaDoc(request.getParameter("year")).intValue());
274             day.set(GregorianCalendar.HOUR_OF_DAY, 0);
275             day.set(GregorianCalendar.MINUTE, 0);
276             day.set(GregorianCalendar.SECOND, 0);
277             day.set(GregorianCalendar.MILLISECOND, 0);
278         }
279
280         // sort out the help key, include page, window size and events from
281
// the view
282

283         // ------- DAY -------
284
if (IndexFormConstants.VIEW_DAY.equals(view)) {
285             indexForm.setViewPage("/calendar/dayview.jsp");
286             indexForm.setHelpKey("calendar.day");
287
288             // look for next, previous day
289
if (request.getParameter("next") != null) {
290                 day.set(GregorianCalendar.DAY_OF_YEAR,
291                     day.get(GregorianCalendar.DAY_OF_YEAR) + 1);
292             } else if (request.getParameter("previous") != null) {
293                 day.set(GregorianCalendar.DAY_OF_YEAR,
294                     day.get(GregorianCalendar.DAY_OF_YEAR)-1);
295             }
296             Map JavaDoc eventsDay = new HashMap JavaDoc();
297             Map JavaDoc [] events = {eventsDay};
298             indexForm.setEvents(events);
299             Vector JavaDoc allDayEventsDay = new Vector JavaDoc();
300             Vector JavaDoc [] allDayEvents = {allDayEventsDay};
301             indexForm.setAllDayEvents(allDayEvents);
302             findDayEvents(securitySession, indexForm, day, allDayEventsDay, eventsDay);
303
304         } else {
305             // in the settings table, 1=MONDAY 0=SUNDAY --%>
306
int firstDay;
307             firstDay =
308                 (settings
309                     .getIntegerSetting(
310                         securitySession,
311                         "calendarFirstWeekDay",
312                         user))
313                     .intValue();
314
315             // if this is a 5 day view, monday is always the first
316
int numberOfDays = 7;
317             if (IndexFormConstants.VIEW_WORK_WEEK.equals(view)) {
318                 firstDay = 1;
319                 numberOfDays = 5;
320             }
321
322             // now work out the first day of the week to show - note for
323
// month/year views it is only the day of the week for this
324
// day which is significant (not its actual date)
325
GregorianCalendar JavaDoc firstWeekDay = new GregorianCalendar JavaDoc(timeZone);
326             GregorianCalendar JavaDoc firstMonthDay = null;
327
328             // if this is month view, go to the start of the month
329
if (IndexFormConstants.VIEW_MONTH.equals(view)) {
330                 // look for next, previous month
331
if (request.getParameter("next") != null) {
332                     day.set(GregorianCalendar.MONTH,
333                         day.get(GregorianCalendar.MONTH) + 1);
334                 } else if (request.getParameter("previous") != null) {
335                     day.set(GregorianCalendar.MONTH,
336                         day.get(GregorianCalendar.MONTH) - 1);
337                 }
338
339                 firstMonthDay = new GregorianCalendar JavaDoc(timeZone);
340                 firstMonthDay.setTime(day.getTime());
341                 firstMonthDay.set(GregorianCalendar.DAY_OF_MONTH, 1);
342                 firstWeekDay.setTime(firstMonthDay.getTime());
343             } else {
344                 // look for next, previous week
345
if (request.getParameter("next") != null) {
346                     day.set(GregorianCalendar.DAY_OF_YEAR,
347                         day.get(GregorianCalendar.DAY_OF_YEAR) + 7);
348                 } else if (request.getParameter("previous") != null) {
349                     day.set(GregorianCalendar.DAY_OF_YEAR,
350                         day.get(GregorianCalendar.DAY_OF_YEAR)-7);
351                 }
352
353                 // if this is a week view, just go to the current day
354
firstWeekDay.setTime(day.getTime());
355             }
356
357             firstWeekDay.set(GregorianCalendar.DAY_OF_YEAR,
358                     firstWeekDay.get(GregorianCalendar.DAY_OF_YEAR)
359                     - ((firstWeekDay.get(GregorianCalendar.DAY_OF_WEEK) + 6 - firstDay) % 7) );
360             firstWeekDay.set(GregorianCalendar.HOUR_OF_DAY, 0);
361             firstWeekDay.set(GregorianCalendar.MINUTE, 0);
362             firstWeekDay.set(GregorianCalendar.SECOND, 0);
363             firstWeekDay.set(GregorianCalendar.MILLISECOND, 0);
364             indexForm.setFirstWeekDay(firstWeekDay);
365
366             // temporary variable used for counting forward
367
GregorianCalendar JavaDoc thisDay = new GregorianCalendar JavaDoc(timeZone);
368
369             // basically now it breaks down into month or week
370
// ------- MONTH -------
371
if (IndexFormConstants.VIEW_MONTH.equals(view)) {
372                 // month view doesn't separate all day events from normal
373
// events - just go thro' all events each day and add them
374
// to a tree set sorted by hour
375

376                 // first work out how many weeks there are
377
int dayOfWeek = firstWeekDay.get(GregorianCalendar.DAY_OF_WEEK);
378                 int dayBeforeOfWeek = dayOfWeek - 1;
379                 if (dayBeforeOfWeek < 0) {
380                     dayBeforeOfWeek += 7;
381                 }
382                 int twoDaysBeforeOfWeek = dayBeforeOfWeek - 1;
383                 if (twoDaysBeforeOfWeek < 0) {
384                     twoDaysBeforeOfWeek += 7;
385                 }
386                 int numberOfWeeks = 0;
387
388                 // if the first day is first day of week and 28 days in
389
// month then we need 4 weeks
390
if ((firstMonthDay.getActualMaximum(GregorianCalendar.DAY_OF_MONTH) == 28)
391                         && (firstMonthDay.get(GregorianCalendar.DAY_OF_WEEK) == dayOfWeek)) {
392                     numberOfWeeks = 4;
393                 } else if (((firstMonthDay.getActualMaximum(GregorianCalendar.DAY_OF_MONTH)==31)
394                             && (firstMonthDay.get(GregorianCalendar.DAY_OF_WEEK) == twoDaysBeforeOfWeek))
395                         || ((firstMonthDay.get(GregorianCalendar.DAY_OF_WEEK) == dayBeforeOfWeek)
396                             && (firstMonthDay.getActualMaximum(GregorianCalendar.DAY_OF_MONTH) >=30))) {
397                     // e.g. if you have a sunday as the first day of the week,
398
// friday as the first day with 31 days or saturday as
399
// the first day with 30/31 will mean 6 weeks
400
// if you have a monday as the first day of the week,
401
// saturday as the first day with 31 days or sunday as
402
// the first day with 30/31 will mean 6 weeks
403
numberOfWeeks = 6;
404                 // default: we need 5 weeks
405
} else {
406                     numberOfWeeks = 5;
407                 }
408
409                 Map JavaDoc [] events = new Map JavaDoc[numberOfWeeks];
410                 indexForm.setEvents(events);
411                 // go thro' all the weeks
412
int thisMonth = firstMonthDay.get(GregorianCalendar.MONTH);
413                 thisDay.setTime(firstWeekDay.getTime());
414                 for (int week = 0; week < numberOfWeeks; ++week) {
415                     events[week] = new HashMap JavaDoc();
416                     // go thro' all the days
417
for (int dayNumber = 0; dayNumber < 7; ++dayNumber) {
418                         // if this day is in the month, set the events
419
// (it might be in the month before or after -
420
// the value for their keys are null to set them
421
// apart)
422
if (thisMonth==thisDay.get(GregorianCalendar.MONTH)) {
423                             // set the events for each day
424
EventHourComparator comparator = new EventHourComparator();
425                             comparator.setDay(thisDay);
426                             TreeSet JavaDoc eventsThisDay = new TreeSet JavaDoc(comparator);
427                             eventsThisDay.addAll(calendar.findEventsForDay(securitySession, thisDay));
428                             events[week].put(new Integer JavaDoc(dayNumber), eventsThisDay);
429                         }
430                         thisDay.set(GregorianCalendar.DAY_OF_YEAR,
431                           thisDay.get(GregorianCalendar.DAY_OF_YEAR) + 1);
432                     }
433                 }
434
435                 indexForm.setViewPage("/calendar/monthview.jsp");
436                 indexForm.setHelpKey("calendar.month");
437
438             // ------- WEEK -------
439
} else {
440                 // if chosen day is saturday or sunday make 7 days view
441
if ((day.get(GregorianCalendar.DAY_OF_WEEK)==GregorianCalendar.SATURDAY)
442                         || (day.get(GregorianCalendar.DAY_OF_WEEK)==GregorianCalendar.SUNDAY)) {
443                     indexForm.setView(view = IndexFormConstants.VIEW_WEEK);
444                 }
445
446                 // go thro' all of the days and create the maps of tree sets
447
// and the vectors
448
Map JavaDoc [] events = new Map JavaDoc[numberOfDays];
449                 indexForm.setEvents(events);
450                 Vector JavaDoc [] allDayEvents = new Vector JavaDoc[numberOfDays];
451                 indexForm.setAllDayEvents(allDayEvents);
452                 thisDay.setTime(firstWeekDay.getTime());
453                 for (int index = 0; index < numberOfDays; ++index) {
454                     events[index] = new HashMap JavaDoc();
455                     allDayEvents[index] = new Vector JavaDoc();
456                     findDayEvents(securitySession, indexForm, thisDay,
457                             allDayEvents[index], events[index]);
458                     thisDay.set(GregorianCalendar.DAY_OF_YEAR,
459                       thisDay.get(GregorianCalendar.DAY_OF_YEAR) + 1);
460                 }
461
462                 indexForm.setViewPage("/calendar/weekview.jsp");
463                 indexForm.setHelpKey("calendar.week");
464             }
465
466         }
467
468         // this form always returns to the input screen
469
// I think this is not necesary because day is not new instance !!
470
//indexForm.setCurrentDay(day);
471
return null;
472     }
473
474     /**
475      * <p>This helper method finds the events for the day specified and
476      * splits them into all day events, and normal events. Normal events
477      * are
478      * sorted in a hash map, indexed by the hour of day they either start
479      * or
480      * (if they start on a day before the current day) end.</p>
481      *
482      * @param calendar remote interface instance to the server-side
483      * calendar facade.
484      * @param indexForm the current index form with details to be listed.
485      * @param day defines the day to retrieve events for.
486      * @param allDayEvents a <code>Vector</code> into which all of the
487      * events marked as all day events are loaded.
488      * @param events <code>Map</code> into which normal events
489      * are stored indexed by the time they happen.
490      * @param userName current user name from session. .
491      * @param settings valid, non-null settings from session.
492      * @exception SystemException if there is any remote
493      * excepotion accessing server-side methods.
494      */

495     private void findDayEvents(final SecuritySession securitySession,
496             final IndexForm indexForm,
497             final GregorianCalendar JavaDoc day,
498             final Vector JavaDoc allDayEvents,
499             final Map JavaDoc events) throws SystemException {
500         // this comparator will be used to construct the tree maps
501
EventHourComparator comparator = new EventHourComparator();
502         comparator.setDay(day);
503
504         Collection JavaDoc eventsForDay;
505         eventsForDay = calendar.findEventsForDay(securitySession, day);
506         String JavaDoc fromKey, toKey;
507
508         // TODO:
509
dateFormatter.setDateFormat(DateFormatterConstants.DATE_LONG_DAY);
510         dateFormatter.setTimeFormat(DateFormatterConstants.TIME_SHORT);
511
512         // sort all events into all day events and ordinary ones
513
// all day events go into the special vector, ordinary ones
514
// go into the map to sort them
515
for (Iterator JavaDoc i = eventsForDay.iterator(); i.hasNext(); ) {
516             EventDO event = (EventDO) i.next();
517
518             Integer JavaDoc key = null;
519             // does the event start before today and finish after today?
520
// OR it is marked as an all day event?
521
if (event.isAllDayEvent()
522                     || (comparator.isAfterDay(event) && (event.getStart().before(day)))) {
523                 allDayEvents.add(event);
524
525             // if ordinary events start today, it's the start time which is
526
// important
527
} else if (!event.getStart().before(day)) {
528                 // the start hour is our key
529
key = new Integer JavaDoc(event.getStart().get(GregorianCalendar.HOUR_OF_DAY));
530
531                 // set up starting hour of the first event this day
532
if (event.getStart().get(GregorianCalendar.HOUR_OF_DAY) < indexForm.getDayStartHour()) {
533                     indexForm.setDayStartHour(event.getStart().get(GregorianCalendar.HOUR_OF_DAY));
534                 }
535                 // set up starting hour of the last event this day
536
if (event.getStart().get(GregorianCalendar.HOUR_OF_DAY) > indexForm.getDayFinishHour()) {
537                     indexForm.setDayFinishHour(event.getStart().get(GregorianCalendar.HOUR_OF_DAY));
538
539                 }
540
541             // if the event finishes today but started before today, it is the
542
// to time which is important
543
} else if (!comparator.isAfterDay(event)) {
544                 // the finish hour is our key
545
key = new Integer JavaDoc(event.getFinish().get(GregorianCalendar.HOUR_OF_DAY));
546
547                 // set up finishing hour of the last event at the day
548
if (event.getFinish().get(GregorianCalendar.HOUR_OF_DAY) > indexForm.getDayFinishHour()) {
549                     indexForm.setDayFinishHour(event.getFinish().get(GregorianCalendar.HOUR_OF_DAY));
550                 }
551                 if (event.getFinish().get(GregorianCalendar.HOUR_OF_DAY) < indexForm.getDayStartHour()) {
552                     indexForm.setDayStartHour(event.getFinish().get(GregorianCalendar.HOUR_OF_DAY));
553                 }
554             }
555             // if this was a normal event, set it in the tree set
556
if (key != null) {
557                 // see if there is already a tree set at this hour
558
TreeSet JavaDoc treeSet = (TreeSet JavaDoc) events.get(key);
559                 if (treeSet == null) {
560                     // if there is no tree set at this hour, make an empty one
561
events.put(key, treeSet = new TreeSet JavaDoc(comparator));
562                 }
563                 treeSet.add(event);
564             }
565         }
566     }
567 }
568
Popular Tags