1
22
23 package com.liferay.portlet.calendar.service.impl;
24
25 import com.liferay.counter.service.CounterLocalServiceUtil;
26 import com.liferay.mail.service.MailServiceUtil;
27 import com.liferay.portal.NoSuchUserException;
28 import com.liferay.portal.PortalException;
29 import com.liferay.portal.SystemException;
30 import com.liferay.portal.im.AIMConnector;
31 import com.liferay.portal.im.ICQConnector;
32 import com.liferay.portal.im.MSNConnector;
33 import com.liferay.portal.im.YMConnector;
34 import com.liferay.portal.kernel.cal.DayAndPosition;
35 import com.liferay.portal.kernel.cal.Recurrence;
36 import com.liferay.portal.kernel.mail.MailMessage;
37 import com.liferay.portal.kernel.util.Base64;
38 import com.liferay.portal.kernel.util.CalendarFactoryUtil;
39 import com.liferay.portal.kernel.util.LocaleUtil;
40 import com.liferay.portal.kernel.util.StringPool;
41 import com.liferay.portal.kernel.util.StringUtil;
42 import com.liferay.portal.kernel.util.TimeZoneUtil;
43 import com.liferay.portal.kernel.util.Validator;
44 import com.liferay.portal.kernel.uuid.PortalUUIDUtil;
45 import com.liferay.portal.model.Company;
46 import com.liferay.portal.model.Contact;
47 import com.liferay.portal.model.User;
48 import com.liferay.portal.model.impl.ResourceImpl;
49 import com.liferay.portal.service.PortletPreferencesLocalServiceUtil;
50 import com.liferay.portal.service.ResourceLocalServiceUtil;
51 import com.liferay.portal.service.persistence.CompanyUtil;
52 import com.liferay.portal.service.persistence.UserUtil;
53 import com.liferay.portal.util.DateFormats;
54 import com.liferay.portal.util.PortalUtil;
55 import com.liferay.portal.util.PortletKeys;
56 import com.liferay.portal.util.ReleaseInfo;
57 import com.liferay.portlet.calendar.EventDurationException;
58 import com.liferay.portlet.calendar.EventEndDateException;
59 import com.liferay.portlet.calendar.EventStartDateException;
60 import com.liferay.portlet.calendar.EventTitleException;
61 import com.liferay.portlet.calendar.model.CalEvent;
62 import com.liferay.portlet.calendar.model.impl.CalEventImpl;
63 import com.liferay.portlet.calendar.service.base.CalEventLocalServiceBaseImpl;
64 import com.liferay.portlet.calendar.service.persistence.CalEventFinder;
65 import com.liferay.portlet.calendar.service.persistence.CalEventUtil;
66 import com.liferay.portlet.calendar.util.CalUtil;
67 import com.liferay.util.Time;
68 import com.liferay.util.cal.CalendarUtil;
69 import com.liferay.util.servlet.ServletResponseUtil;
70
71 import java.io.BufferedOutputStream;
72 import java.io.File;
73 import java.io.FileOutputStream;
74 import java.io.FileReader;
75 import java.io.IOException;
76 import java.io.OutputStream;
77
78 import java.text.DateFormat;
79
80 import java.util.ArrayList;
81 import java.util.Calendar;
82 import java.util.Collection;
83 import java.util.Date;
84 import java.util.Iterator;
85 import java.util.List;
86 import java.util.Locale;
87 import java.util.Map;
88 import java.util.TimeZone;
89
90 import javax.mail.internet.InternetAddress;
91
92 import javax.portlet.PortletPreferences;
93
94 import net.fortuna.ical4j.data.CalendarBuilder;
95 import net.fortuna.ical4j.data.CalendarOutputter;
96 import net.fortuna.ical4j.data.ParserException;
97 import net.fortuna.ical4j.model.Component;
98 import net.fortuna.ical4j.model.DateTime;
99 import net.fortuna.ical4j.model.Parameter;
100 import net.fortuna.ical4j.model.Property;
101 import net.fortuna.ical4j.model.PropertyList;
102 import net.fortuna.ical4j.model.Recur;
103 import net.fortuna.ical4j.model.WeekDay;
104 import net.fortuna.ical4j.model.component.VEvent;
105 import net.fortuna.ical4j.model.component.VTimeZone;
106 import net.fortuna.ical4j.model.property.CalScale;
107 import net.fortuna.ical4j.model.property.Comment;
108 import net.fortuna.ical4j.model.property.Description;
109 import net.fortuna.ical4j.model.property.DtStart;
110 import net.fortuna.ical4j.model.property.Duration;
111 import net.fortuna.ical4j.model.property.ProdId;
112 import net.fortuna.ical4j.model.property.RRule;
113 import net.fortuna.ical4j.model.property.Summary;
114 import net.fortuna.ical4j.model.property.Uid;
115 import net.fortuna.ical4j.model.property.Version;
116
117 import org.apache.commons.logging.Log;
118 import org.apache.commons.logging.LogFactory;
119
120
127 public class CalEventLocalServiceImpl extends CalEventLocalServiceBaseImpl {
128
129 public CalEvent addEvent(
130 long userId, long plid, String title, String description,
131 int startDateMonth, int startDateDay, int startDateYear,
132 int startDateHour, int startDateMinute, int endDateMonth,
133 int endDateDay, int endDateYear, int durationHour,
134 int durationMinute, boolean allDay, boolean timeZoneSensitive,
135 String type, boolean repeating, Recurrence recurrence,
136 String remindBy, int firstReminder, int secondReminder,
137 boolean addCommunityPermissions, boolean addGuestPermissions)
138 throws PortalException, SystemException {
139
140 return addEvent(
141 userId, plid, title, description, startDateMonth, startDateDay,
142 startDateYear, startDateHour, startDateMinute, endDateMonth,
143 endDateDay, endDateYear, durationHour, durationMinute, allDay,
144 timeZoneSensitive, type, repeating, recurrence, remindBy,
145 firstReminder, secondReminder,
146 Boolean.valueOf(addCommunityPermissions),
147 Boolean.valueOf(addGuestPermissions), null, null);
148 }
149
150 public CalEvent addEvent(
151 long userId, long plid, String title, String description,
152 int startDateMonth, int startDateDay, int startDateYear,
153 int startDateHour, int startDateMinute, int endDateMonth,
154 int endDateDay, int endDateYear, int durationHour,
155 int durationMinute, boolean allDay, boolean timeZoneSensitive,
156 String type, boolean repeating, Recurrence recurrence,
157 String remindBy, int firstReminder, int secondReminder,
158 String[] communityPermissions, String[] guestPermissions)
159 throws PortalException, SystemException {
160
161 return addEvent(
162 userId, plid, title, description, startDateMonth, startDateDay,
163 startDateYear, startDateHour, startDateMinute, endDateMonth,
164 endDateDay, endDateYear, durationHour, durationMinute, allDay,
165 timeZoneSensitive, type, repeating, recurrence, remindBy,
166 firstReminder, secondReminder, null, null, communityPermissions,
167 guestPermissions);
168 }
169
170 public CalEvent addEvent(
171 long userId, long plid, String title, String description,
172 int startDateMonth, int startDateDay, int startDateYear,
173 int startDateHour, int startDateMinute, int endDateMonth,
174 int endDateDay, int endDateYear, int durationHour,
175 int durationMinute, boolean allDay, boolean timeZoneSensitive,
176 String type, boolean repeating, Recurrence recurrence,
177 String remindBy, int firstReminder, int secondReminder,
178 Boolean addCommunityPermissions, Boolean addGuestPermissions,
179 String[] communityPermissions, String[] guestPermissions)
180 throws PortalException, SystemException {
181
182
184 User user = UserUtil.findByPrimaryKey(userId);
185 long groupId = PortalUtil.getPortletGroupId(plid);
186 Date now = new Date();
187
188 Locale locale = null;
189 TimeZone timeZone = null;
190
191 if (timeZoneSensitive) {
192 locale = user.getLocale();
193 timeZone = user.getTimeZone();
194 }
195 else {
196 locale = LocaleUtil.getDefault();
197 timeZone = TimeZoneUtil.getDefault();
198 }
199
200 Calendar startDate = CalendarFactoryUtil.getCalendar(timeZone, locale);
201
202 startDate.set(Calendar.MONTH, startDateMonth);
203 startDate.set(Calendar.DATE, startDateDay);
204 startDate.set(Calendar.YEAR, startDateYear);
205 startDate.set(Calendar.HOUR_OF_DAY, startDateHour);
206 startDate.set(Calendar.MINUTE, startDateMinute);
207 startDate.set(Calendar.SECOND, 0);
208 startDate.set(Calendar.MILLISECOND, 0);
209
210 Calendar endDate = CalendarFactoryUtil.getCalendar(timeZone, locale);
211
212 endDate.set(Calendar.MONTH, endDateMonth);
213 endDate.set(Calendar.DATE, endDateDay);
214 endDate.set(Calendar.YEAR, endDateYear);
215 endDate.set(Calendar.HOUR_OF_DAY, 23);
216 endDate.set(Calendar.MINUTE, 59);
217 endDate.set(Calendar.SECOND, 59);
218 endDate.set(Calendar.MILLISECOND, 999);
219
220 if (allDay) {
221 startDate.set(Calendar.HOUR_OF_DAY, 0);
222 startDate.set(Calendar.MINUTE, 0);
223
224 durationHour = 24;
225 durationMinute = 0;
226 }
227
228 validate(
229 title, startDateMonth, startDateDay, startDateYear, endDateMonth,
230 endDateDay, endDateYear, durationHour, durationMinute, allDay);
231
232 long eventId = CounterLocalServiceUtil.increment();
233
234 CalEvent event = CalEventUtil.create(eventId);
235
236 event.setGroupId(groupId);
237 event.setCompanyId(user.getCompanyId());
238 event.setUserId(user.getUserId());
239 event.setUserName(user.getFullName());
240 event.setCreateDate(now);
241 event.setModifiedDate(now);
242 event.setTitle(title);
243 event.setDescription(description);
244 event.setStartDate(startDate.getTime());
245 event.setEndDate(endDate.getTime());
246 event.setDurationHour(durationHour);
247 event.setDurationMinute(durationMinute);
248 event.setAllDay(allDay);
249 event.setTimeZoneSensitive(timeZoneSensitive);
250 event.setType(type);
251 event.setRepeating(repeating);
252 event.setRecurrence(Base64.objectToString(recurrence));
253 event.setRemindBy(remindBy);
254 event.setFirstReminder(firstReminder);
255 event.setSecondReminder(secondReminder);
256
257 CalEventUtil.update(event);
258
259
261 if ((addCommunityPermissions != null) &&
262 (addGuestPermissions != null)) {
263
264 addEventResources(
265 event, addCommunityPermissions.booleanValue(),
266 addGuestPermissions.booleanValue());
267 }
268 else {
269 addEventResources(event, communityPermissions, guestPermissions);
270 }
271
272
274 CalEventLocalUtil.clearEventsPool(event.getGroupId());
275
276 return event;
277 }
278
279 public void addEventResources(
280 long eventId, boolean addCommunityPermissions,
281 boolean addGuestPermissions)
282 throws PortalException, SystemException {
283
284 CalEvent event = CalEventUtil.findByPrimaryKey(eventId);
285
286 addEventResources(
287 event, addCommunityPermissions, addGuestPermissions);
288 }
289
290 public void addEventResources(
291 CalEvent event, boolean addCommunityPermissions,
292 boolean addGuestPermissions)
293 throws PortalException, SystemException {
294
295 ResourceLocalServiceUtil.addResources(
296 event.getCompanyId(), event.getGroupId(), event.getUserId(),
297 CalEvent.class.getName(), event.getEventId(), false,
298 addCommunityPermissions, addGuestPermissions);
299 }
300
301 public void addEventResources(
302 long eventId, String[] communityPermissions,
303 String[] guestPermissions)
304 throws PortalException, SystemException {
305
306 CalEvent event = CalEventUtil.findByPrimaryKey(eventId);
307
308 addEventResources(event, communityPermissions, guestPermissions);
309 }
310
311 public void addEventResources(
312 CalEvent event, String[] communityPermissions,
313 String[] guestPermissions)
314 throws PortalException, SystemException {
315
316 ResourceLocalServiceUtil.addModelResources(
317 event.getCompanyId(), event.getGroupId(), event.getUserId(),
318 CalEvent.class.getName(), event.getEventId(), communityPermissions,
319 guestPermissions);
320 }
321
322 public void checkEvents() throws PortalException, SystemException {
323 Iterator itr = CalEventFinder.findByRemindBy().iterator();
324
325 while (itr.hasNext()) {
326 CalEvent event = (CalEvent)itr.next();
327
328 User user = UserUtil.findByPrimaryKey(event.getUserId());
329
330 Calendar now = CalendarFactoryUtil.getCalendar(
331 user.getTimeZone(), user.getLocale());
332
333 if (!event.isTimeZoneSensitive()) {
334 Calendar temp = CalendarFactoryUtil.getCalendar();
335
336 temp.setTime(Time.getDate(now));
337
338 now = temp;
339 }
340
341 Calendar startDate = null;
342
343 if (event.isTimeZoneSensitive()) {
344 startDate = CalendarFactoryUtil.getCalendar(
345 user.getTimeZone(), user.getLocale());
346 }
347 else {
348 startDate = CalendarFactoryUtil.getCalendar();
349 }
350
351 startDate.setTime(event.getStartDate());
352
353 long diff =
354 (startDate.getTime().getTime() - now.getTime().getTime()) /
355 Time.MINUTE;
356
357 if ((diff == (event.getFirstReminder() / Time.MINUTE)) ||
358 (diff == (event.getSecondReminder() / Time.MINUTE))) {
359
360 remindUser(event, user);
361 }
362 }
363 }
364
365 public void deleteEvent(long eventId)
366 throws PortalException, SystemException {
367
368 CalEvent event = CalEventUtil.findByPrimaryKey(eventId);
369
370 deleteEvent(event);
371 }
372
373 public void deleteEvent(CalEvent event)
374 throws PortalException, SystemException {
375
376
378 CalEventLocalUtil.clearEventsPool(event.getGroupId());
379
380
382 ResourceLocalServiceUtil.deleteResource(
383 event.getCompanyId(), CalEvent.class.getName(),
384 ResourceImpl.SCOPE_INDIVIDUAL, event.getEventId());
385
386
388 CalEventUtil.remove(event.getEventId());
389 }
390
391 public void deleteEvents(long groupId)
392 throws PortalException, SystemException {
393
394 Iterator itr = CalEventUtil.findByGroupId(groupId).iterator();
395
396 while (itr.hasNext()) {
397 CalEvent event = (CalEvent)itr.next();
398
399 deleteEvent(event);
400 }
401 }
402
403 public File exportEvent(long userId, long eventId)
404 throws PortalException, SystemException {
405
406 List events = new ArrayList();
407
408 CalEvent event = CalEventUtil.findByPrimaryKey(eventId);
409
410 events.add(event);
411
412 return exportICal4j(toICalCalendar(userId, events), null);
413 }
414
415 public File exportGroupEvents(long userId, long plid, String fileName)
416 throws PortalException, SystemException {
417
418 long groupId = PortalUtil.getPortletGroupId(plid);
419
420 List events = CalEventUtil.findByGroupId(groupId);
421
422 return exportICal4j(toICalCalendar(userId, events), fileName);
423 }
424
425 public CalEvent getEvent(long eventId)
426 throws PortalException, SystemException {
427
428 return CalEventUtil.findByPrimaryKey(eventId);
429 }
430
431 public List getEvents(long groupId, String type, int begin, int end)
432 throws SystemException {
433
434 if (Validator.isNull(type)) {
435 return CalEventUtil.findByGroupId(groupId, begin, end);
436 }
437 else {
438 return CalEventUtil.findByG_T(groupId, type, begin, end);
439 }
440 }
441
442 public List getEvents(long groupId, Calendar cal) throws SystemException {
443 Map eventsPool = CalEventLocalUtil.getEventsPool(groupId);
444
445 String key = CalUtil.toString(cal);
446
447 List events = (List)eventsPool.get(key);
448
449 if (events == null) {
450
451
453 Collection eventsCol1 = CalEventFinder.findByG_SD(
454 groupId, CalendarUtil.getGTDate(cal),
455 CalendarUtil.getLTDate(cal), true);
456
457
459 Calendar tzICal = CalendarFactoryUtil.getCalendar(
460 cal.get(Calendar.YEAR),
461 cal.get(Calendar.MONTH),
462 cal.get(Calendar.DATE));
463
464 Collection eventsCol2 = CalEventFinder.findByG_SD(
465 groupId, CalendarUtil.getGTDate(tzICal),
466 CalendarUtil.getLTDate(tzICal), false);
467
468
470 events = new ArrayList();
471 events.addAll(eventsCol1);
472 events.addAll(eventsCol2);
473
474
476 Iterator itr = getRepeatingEvents(groupId).iterator();
477
478 while (itr.hasNext()) {
479 CalEvent event = (CalEvent)itr.next();
480
481 Recurrence recurrence = event.getRecurrenceObj();
482
483 try {
484
485
487 if ((recurrence.getFrequency() == Recurrence.DAILY) &&
488 (recurrence.getInterval() <= 0)) {
489
490 recurrence.setInterval(1);
491
492 event.setRecurrence(Base64.objectToString(recurrence));
493
494 event = CalEventUtil.update(event);
495
496 recurrence = event.getRecurrenceObj();
497 }
498
499 if (recurrence.isInRecurrence(
500 getRecurrenceCal(cal, tzICal, event))) {
501
502 events.add(event);
503 }
504 }
505 catch (Exception e) {
506 _log.error(e.getMessage());
507 }
508 }
509
510 eventsPool.put(key, events);
511 }
512
513 return events;
514 }
515
516 public List getEvents(long groupId, Calendar cal, String type)
517 throws SystemException {
518
519 List events = getEvents(groupId, cal);
520
521 if (Validator.isNull(type)) {
522 return events;
523 }
524 else {
525 events = new ArrayList(events);
526
527 Iterator itr = events.iterator();
528
529 while (itr.hasNext()) {
530 CalEvent event = (CalEvent)itr.next();
531
532 if (!event.getType().equals(type)) {
533 itr.remove();
534 }
535 }
536
537 return events;
538 }
539 }
540
541 public int getEventsCount(long groupId, String type)
542 throws SystemException {
543
544 if (Validator.isNull(type)) {
545 return CalEventUtil.countByGroupId(groupId);
546 }
547 else {
548 return CalEventUtil.countByG_T(groupId, type);
549 }
550 }
551
552 public List getRepeatingEvents(long groupId) throws SystemException {
553 Map eventsPool = CalEventLocalUtil.getEventsPool(groupId);
554
555 String key = "recurrence";
556
557 List events = (List)eventsPool.get(key);
558
559 if (events == null) {
560 events = CalEventUtil.findByG_R(groupId, true);
561
562 eventsPool.put(key, events);
563 }
564
565 return events;
566 }
567
568 public boolean hasEvents(long groupId, Calendar cal)
569 throws SystemException {
570
571 return hasEvents(groupId, cal, null);
572 }
573
574 public boolean hasEvents(long groupId, Calendar cal, String type)
575 throws SystemException {
576
577 if (getEvents(groupId, cal, type).size() > 0) {
578 return true;
579 }
580 else {
581 return false;
582 }
583 }
584
585 public void importICal4j(long userId, long plid, File file)
586 throws PortalException, SystemException {
587
588 try {
589 CalendarBuilder builder = new CalendarBuilder();
590
591 net.fortuna.ical4j.model.Calendar calendar = builder.build(
592 new FileReader(file));
593
594 TimeZone timeZone = toTimeZone(
595 userId, (VTimeZone)calendar.getComponent(Component.VTIMEZONE));
596
597 Iterator itr = calendar.getComponents(Component.VEVENT).iterator();
598
599 while (itr.hasNext()) {
600 VEvent vEvent = (VEvent)itr.next();
601
602 importICal4j(userId, plid, vEvent, timeZone);
603 }
604 }
605 catch (IOException ioe) {
606 throw new SystemException(ioe.getMessage());
607 }
608 catch (ParserException pe) {
609 throw new SystemException(pe.getMessage());
610 }
611 }
612
613 public CalEvent updateEvent(
614 long userId, long eventId, String title, String description,
615 int startDateMonth, int startDateDay, int startDateYear,
616 int startDateHour, int startDateMinute, int endDateMonth,
617 int endDateDay, int endDateYear, int durationHour,
618 int durationMinute, boolean allDay, boolean timeZoneSensitive,
619 String type, boolean repeating, Recurrence recurrence,
620 String remindBy, int firstReminder, int secondReminder)
621 throws PortalException, SystemException {
622
623 User user = UserUtil.findByPrimaryKey(userId);
624
625 Locale locale = null;
626 TimeZone timeZone = null;
627
628 if (timeZoneSensitive) {
629 locale = user.getLocale();
630 timeZone = user.getTimeZone();
631 }
632 else {
633 locale = LocaleUtil.getDefault();
634 timeZone = TimeZoneUtil.getDefault();
635 }
636
637 Calendar startDate = CalendarFactoryUtil.getCalendar(timeZone, locale);
638
639 startDate.set(Calendar.MONTH, startDateMonth);
640 startDate.set(Calendar.DATE, startDateDay);
641 startDate.set(Calendar.YEAR, startDateYear);
642 startDate.set(Calendar.HOUR_OF_DAY, startDateHour);
643 startDate.set(Calendar.MINUTE, startDateMinute);
644 startDate.set(Calendar.SECOND, 0);
645 startDate.set(Calendar.MILLISECOND, 0);
646
647 Calendar endDate = CalendarFactoryUtil.getCalendar(timeZone, locale);
648
649 endDate.set(Calendar.MONTH, endDateMonth);
650 endDate.set(Calendar.DATE, endDateDay);
651 endDate.set(Calendar.YEAR, endDateYear);
652 endDate.set(Calendar.HOUR_OF_DAY, 23);
653 endDate.set(Calendar.MINUTE, 59);
654 endDate.set(Calendar.SECOND, 59);
655 endDate.set(Calendar.MILLISECOND, 999);
656
657 if (allDay) {
658 startDate.set(Calendar.HOUR_OF_DAY, 0);
659 startDate.set(Calendar.MINUTE, 0);
660
661 durationHour = 24;
662 durationMinute = 0;
663 }
664
665 validate(
666 title, startDateMonth, startDateDay, startDateYear, endDateMonth,
667 endDateDay, endDateYear, durationHour, durationMinute, allDay);
668
669 CalEvent event = CalEventUtil.findByPrimaryKey(eventId);
670
671 event.setModifiedDate(new Date());
672 event.setTitle(title);
673 event.setDescription(description);
674 event.setStartDate(startDate.getTime());
675 event.setEndDate(endDate.getTime());
676 event.setDurationHour(durationHour);
677 event.setDurationMinute(durationMinute);
678 event.setAllDay(allDay);
679 event.setTimeZoneSensitive(timeZoneSensitive);
680 event.setType(type);
681 event.setRepeating(repeating);
682 event.setRecurrence(Base64.objectToString(recurrence));
683 event.setRemindBy(remindBy);
684 event.setFirstReminder(firstReminder);
685 event.setSecondReminder(secondReminder);
686
687 CalEventUtil.update(event);
688
689 CalEventLocalUtil.clearEventsPool(event.getGroupId());
690
691 return event;
692 }
693
694 protected File exportICal4j(
695 net.fortuna.ical4j.model.Calendar cal, String fileName)
696 throws SystemException {
697
698 OutputStream os = null;
699
700 try {
701 String extension = ".ics";
702
703 if (Validator.isNull(fileName)) {
704 fileName = "liferay.";
705 }
706 else {
707 int pos = fileName.lastIndexOf(StringPool.PERIOD);
708
709 if (pos != -1) {
710 extension = fileName.substring(pos);
711 fileName = fileName.substring(0, pos);
712 }
713 }
714
715 File file = File.createTempFile(fileName, extension);
716
717 os = new BufferedOutputStream(new FileOutputStream(file.getPath()));
718
719 CalendarOutputter calOutput = new CalendarOutputter();
720
721 calOutput.output(cal, os);
722
723 return file;
724 }
725 catch (Exception e) {
726 _log.error(e, e);
727
728 throw new SystemException(e);
729 }
730 finally {
731 ServletResponseUtil.cleanUp(os);
732 }
733 }
734
735 protected Calendar getRecurrenceCal(
736 Calendar cal, Calendar tzICal, CalEvent event) {
737
738 Calendar eventCal = CalendarFactoryUtil.getCalendar();
739 eventCal.setTime(event.getStartDate());
740
741 Calendar recurrenceCal = (Calendar)tzICal.clone();
742 recurrenceCal.set(
743 Calendar.HOUR_OF_DAY, eventCal.get(Calendar.HOUR_OF_DAY));
744 recurrenceCal.set(
745 Calendar.MINUTE, eventCal.get(Calendar.MINUTE));
746 recurrenceCal.set(Calendar.SECOND, 0);
747 recurrenceCal.set(Calendar.MILLISECOND, 0);
748
749 if (event.isTimeZoneSensitive()) {
750 int gmtDate = eventCal.get(Calendar.DATE);
751 long gmtMills = eventCal.getTimeInMillis();
752
753 eventCal.setTimeZone(cal.getTimeZone());
754
755 int tziDate = eventCal.get(Calendar.DATE);
756 long tziMills = Time.getDate(eventCal).getTime();
757
758 if (gmtDate != tziDate) {
759 int diffDate = 0;
760
761 if (gmtMills > tziMills) {
762 diffDate = (int)Math.ceil(
763 (double)(gmtMills - tziMills) / Time.DAY);
764 }
765 else {
766 diffDate = (int)Math.floor(
767 (double)(gmtMills - tziMills) / Time.DAY);
768 }
769
770 recurrenceCal.add(Calendar.DATE, diffDate);
771 }
772 }
773
774 return recurrenceCal;
775 }
776
777 protected void importICal4j(
778 long userId, long plid, VEvent event, TimeZone timeZone)
779 throws PortalException, SystemException {
780
781 String title = StringPool.BLANK;
782
783 if (event.getSummary() != null) {
784 title = event.getSummary().getValue();
785 }
786
787 String description = StringPool.BLANK;
788
789 if (event.getDescription() != null) {
790 description = event.getDescription().getValue();
791 }
792
793 Calendar startDate = Calendar.getInstance(timeZone);
794
795 startDate.setTime(event.getStartDate().getDate());
796
797 Calendar endDate = Calendar.getInstance(timeZone);
798
799 endDate.setTime(event.getEndDate().getDate());
800
801 long diffMillis =
802 endDate.getTimeInMillis() - startDate.getTimeInMillis();
803 long durationHours = diffMillis / (60 * 60 * 1000);
804 long durationMins =
805 (diffMillis / (60 * 1000)) - (durationHours * 60);
806 boolean allDay = false;
807
808 if (event.getProperty(Property.DTSTART).getParameter(
809 Parameter.TZID) == null){
810
811 Calendar startDateWithoutTimeZone = Calendar.getInstance();
812
813 startDateWithoutTimeZone.setTime(
814 event.getStartDate().getDate());
815
816 startDate.set(
817 Calendar.DAY_OF_MONTH,
818 startDateWithoutTimeZone.get(Calendar.DAY_OF_MONTH));
819 startDate.set(Calendar.HOUR_OF_DAY, 0);
820 startDate.set(Calendar.MINUTE, 0);
821 startDate.set(Calendar.SECOND, 0);
822 startDate.set(Calendar.MILLISECOND, 0);
823
824 durationHours = 24;
825 durationMins = 0;
826 allDay = true;
827 }
828
829 boolean timeZoneSensitive = false;
830 String type = StringPool.BLANK;
831 boolean repeating = false;
832 Recurrence recurrence = null;
833
834 RRule rrule = (RRule)event.getProperty(Property.RRULE);
835
836 if (rrule != null) {
837 repeating = true;
838 recurrence = toRecurrence(
839 rrule.getRecur(), timeZone, startDate);
840
841 if (recurrence.getUntil() != null) {
842 endDate = recurrence.getUntil();
843 }
844 }
845
846 String remindBy = "none";
847 int firstReminder = 300000;
848 int secondReminder = 300000;
849
850 boolean addCommunityPermissions = false;
851 boolean addGuestPermissions = false;
852
853 addEvent(
854 userId, plid, title, description, startDate.get(Calendar.MONTH),
855 startDate.get(Calendar.DAY_OF_MONTH),
856 startDate.get(Calendar.YEAR),
857 startDate.get(Calendar.HOUR_OF_DAY),
858 startDate.get(Calendar.MINUTE), endDate.get(Calendar.MONTH),
859 endDate.get(Calendar.DAY_OF_MONTH), endDate.get(Calendar.YEAR),
860 (int)durationHours, (int)durationMins, allDay,
861 timeZoneSensitive, type, repeating, recurrence, remindBy,
862 firstReminder, secondReminder, addCommunityPermissions,
863 addGuestPermissions);
864
865 }
866
867 protected void remindUser(CalEvent event, User user) {
868 String remindBy = event.getRemindBy();
869
870 if (remindBy.equals(CalEventImpl.REMIND_BY_NONE)) {
871 return;
872 }
873
874 try {
875 long ownerId = event.getGroupId();
876 int ownerType = PortletKeys.PREFS_OWNER_TYPE_GROUP;
877 long plid = PortletKeys.PREFS_PLID_SHARED;
878 String portletId = PortletKeys.CALENDAR;
879
880 PortletPreferences prefs =
881 PortletPreferencesLocalServiceUtil.getPreferences(
882 event.getCompanyId(), ownerId, ownerType, plid, portletId);
883
884 Company company = CompanyUtil.findByPrimaryKey(user.getCompanyId());
885
886 Contact contact = user.getContact();
887
888 String portletName = PortalUtil.getPortletTitle(
889 PortletKeys.CALENDAR, user);
890
891 String fromName = CalUtil.getEmailFromName(prefs);
892 String fromAddress = CalUtil.getEmailFromAddress(prefs);
893
894 String toName = user.getFullName();
895 String toAddress = user.getEmailAddress();
896
897 if (remindBy.equals(CalEventImpl.REMIND_BY_SMS)) {
898 toAddress = contact.getSmsSn();
899 }
900
901 String subject = CalUtil.getEmailEventReminderSubject(prefs);
902 String body = CalUtil.getEmailEventReminderBody(prefs);
903
904 DateFormat dateFormatDateTime = DateFormats.getDateTime(
905 user.getLocale(), user.getTimeZone());
906
907 subject = StringUtil.replace(
908 subject,
909 new String[] {
910 "[$EVENT_START_DATE$]",
911 "[$EVENT_TITLE$]",
912 "[$FROM_ADDRESS$]",
913 "[$FROM_NAME$]",
914 "[$PORTAL_URL$]",
915 "[$PORTLET_NAME$]",
916 "[$TO_ADDRESS$]",
917 "[$TO_NAME$]"
918 },
919 new String[] {
920 dateFormatDateTime.format(event.getStartDate()),
921 event.getTitle(),
922 fromAddress,
923 fromName,
924 company.getVirtualHost(),
925 portletName,
926 toAddress,
927 toName,
928 });
929
930 body = StringUtil.replace(
931 body,
932 new String[] {
933 "[$EVENT_START_DATE$]",
934 "[$EVENT_TITLE$]",
935 "[$FROM_ADDRESS$]",
936 "[$FROM_NAME$]",
937 "[$PORTAL_URL$]",
938 "[$PORTLET_NAME$]",
939 "[$TO_ADDRESS$]",
940 "[$TO_NAME$]"
941 },
942 new String[] {
943 dateFormatDateTime.format(event.getStartDate()),
944 event.getTitle(),
945 fromAddress,
946 fromName,
947 company.getVirtualHost(),
948 portletName,
949 toAddress,
950 toName,
951 });
952
953 if (remindBy.equals(CalEventImpl.REMIND_BY_EMAIL) ||
954 remindBy.equals(CalEventImpl.REMIND_BY_SMS)) {
955
956 InternetAddress from = new InternetAddress(
957 fromAddress, fromName);
958
959 InternetAddress to = new InternetAddress(toAddress, toName);
960
961 MailMessage message = new MailMessage(
962 from, to, subject, body, true);
963
964 MailServiceUtil.sendEmail(message);
965 }
966 else if (remindBy.equals(CalEventImpl.REMIND_BY_AIM) &&
967 Validator.isNotNull(contact.getAimSn())) {
968
969 AIMConnector.send(contact.getAimSn(), body);
970 }
971 else if (remindBy.equals(CalEventImpl.REMIND_BY_ICQ) &&
972 Validator.isNotNull(contact.getIcqSn())) {
973
974 ICQConnector.send(contact.getIcqSn(), body);
975 }
976 else if (remindBy.equals(CalEventImpl.REMIND_BY_MSN) &&
977 Validator.isNotNull(contact.getMsnSn())) {
978
979 MSNConnector.send(contact.getMsnSn(), body);
980 }
981 else if (remindBy.equals(CalEventImpl.REMIND_BY_YM) &&
982 Validator.isNotNull(contact.getYmSn())) {
983
984 YMConnector.send(contact.getYmSn(), body);
985 }
986 }
987 catch (Exception e) {
988 _log.error(e);
989 }
990 }
991
992 protected int toCalendarWeekDay(WeekDay weekDay) {
993 int dayOfWeeek = 0;
994
995 if (weekDay.getDay().equals(WeekDay.SU.getDay())) {
996 dayOfWeeek = Calendar.SUNDAY;
997 }
998 else if (weekDay.getDay().equals(WeekDay.MO.getDay())) {
999 dayOfWeeek = Calendar.MONDAY;
1000 }
1001 else if (weekDay.getDay().equals(WeekDay.TU.getDay())) {
1002 dayOfWeeek = Calendar.TUESDAY;
1003 }
1004 else if (weekDay.getDay().equals(WeekDay.WE.getDay())) {
1005 dayOfWeeek = Calendar.WEDNESDAY;
1006 }
1007 else if (weekDay.getDay().equals(WeekDay.TH.getDay())) {
1008 dayOfWeeek = Calendar.THURSDAY;
1009 }
1010 else if (weekDay.getDay().equals(WeekDay.FR.getDay())) {
1011 dayOfWeeek = Calendar.FRIDAY;
1012 }
1013 else if (weekDay.getDay().equals(WeekDay.SA.getDay())) {
1014 dayOfWeeek = Calendar.SATURDAY;
1015 }
1016
1017 return dayOfWeeek;
1018 }
1019
1020 protected net.fortuna.ical4j.model.Calendar toICalCalendar(
1021 long userId, List events)
1022 throws PortalException, SystemException {
1023
1024 net.fortuna.ical4j.model.Calendar iCal =
1025 new net.fortuna.ical4j.model.Calendar();
1026
1027 ProdId prodId = new ProdId(
1028 "-//Liferay Inc//Liferay Portal " + ReleaseInfo.getVersion() +
1029 "//EN");
1030
1031 PropertyList props = iCal.getProperties();
1032
1033 props.add(prodId);
1034 props.add(Version.VERSION_2_0);
1035 props.add(CalScale.GREGORIAN);
1036
1037 User user = UserUtil.findByPrimaryKey(userId);
1038 TimeZone timeZone = user.getTimeZone();
1039
1040 List components = iCal.getComponents();
1041
1042 Iterator itr = events.iterator();
1043
1044 while (itr.hasNext()) {
1045 CalEvent event = (CalEvent)itr.next();
1046
1047 components.add(toICalVEvent(event, timeZone));
1048 }
1049
1050 return iCal;
1051 }
1052
1053 protected Recur toICalRecurrence(Recurrence recurrence) {
1054 Recur recur = null;
1055
1056 int recurrenceType = recurrence.getFrequency();
1057
1058 int interval = recurrence.getInterval();
1059
1060 if (recurrenceType == Recurrence.DAILY) {
1061 recur = new Recur(Recur.DAILY, -1);
1062
1063 if (interval >= 1) {
1064 recur.setInterval(interval);
1065 }
1066
1067 DayAndPosition[] byDay = recurrence.getByDay();
1068
1069 if (byDay != null) {
1070 for (int i = 0; i < byDay.length; i++) {
1071 WeekDay weekDay = toICalWeekDay(byDay[i].getDayOfWeek());
1072
1073 recur.getDayList().add(weekDay);
1074 }
1075 }
1076
1077 }
1078 else if (recurrenceType == Recurrence.WEEKLY) {
1079 recur = new Recur(Recur.WEEKLY, -1);
1080
1081 recur.setInterval(interval);
1082
1083 DayAndPosition[] byDay = recurrence.getByDay();
1084
1085 if (byDay != null) {
1086 for (int i = 0; i < byDay.length; i++) {
1087 WeekDay weekDay = toICalWeekDay(byDay[i].getDayOfWeek());
1088
1089 recur.getDayList().add(weekDay);
1090 }
1091 }
1092 }
1093 else if (recurrenceType == Recurrence.MONTHLY) {
1094 recur = new Recur(Recur.MONTHLY, -1);
1095
1096 recur.setInterval(interval);
1097
1098 int[] byMonthDay = recurrence.getByMonthDay();
1099
1100 if (byMonthDay != null) {
1101 Integer monthDay = new Integer(byMonthDay[0]);
1102
1103 recur.getMonthDayList().add(monthDay);
1104 }
1105 else if (recurrence.getByDay() != null){
1106 DayAndPosition[] byDay = recurrence.getByDay();
1107
1108 WeekDay weekDay = toICalWeekDay(byDay[0].getDayOfWeek());
1109
1110 recur.getDayList().add(weekDay);
1111
1112 Integer position = new Integer(byDay[0].getDayPosition());
1113
1114 recur.getSetPosList().add(position);
1115 }
1116 }
1117 else if (recurrenceType == Recurrence.YEARLY) {
1118 recur = new Recur(Recur.YEARLY, -1);
1119
1120 recur.setInterval(interval);
1121 }
1122
1123 Calendar until = recurrence.getUntil();
1124
1125 if (until != null) {
1126 DateTime dateTime = new DateTime(until.getTime());
1127
1128 recur.setUntil(dateTime);
1129 }
1130
1131 return recur;
1132 }
1133
1134 protected VEvent toICalVEvent(CalEvent event, TimeZone timeZone){
1135 VEvent vEvent = new VEvent();
1136
1137 PropertyList eventProps = vEvent.getProperties();
1138
1139
1141 Uid uid = new Uid(PortalUUIDUtil.generate());
1142
1143 eventProps.add(uid);
1144
1145 DtStart dtStart = new DtStart(new DateTime(event.getStartDate()));
1146
1147 eventProps.add(dtStart);
1148
1149
1151 Calendar cal = Calendar.getInstance();
1152
1153 Date start = cal.getTime();
1154
1155 cal.add(Calendar.HOUR, event.getDurationHour());
1156 cal.add(Calendar.MINUTE, event.getDurationHour());
1157
1158 Date end = cal.getTime();
1159
1160 Duration duration = new Duration(start, end);
1161
1162 eventProps.add(duration);
1163
1164
1166 Summary summary = new Summary(event.getTitle());
1167
1168 eventProps.add(summary);
1169
1170
1172 Description description = new Description(event.getDescription());
1173
1174 eventProps.add(description);
1175
1176
1178 Comment comment = new Comment(event.getType());
1179
1180 eventProps.add(comment);
1181
1182
1184 if (event.isRepeating()) {
1185 Recur recur = toICalRecurrence(event.getRecurrenceObj());
1186
1187 RRule rRule = new RRule(recur);
1188
1189 eventProps.add(rRule);
1190 }
1191
1192 return vEvent;
1193 }
1194
1195 protected WeekDay toICalWeekDay(int dayOfWeek) {
1196 WeekDay weekDay = null;
1197
1198 if (dayOfWeek == Calendar.SUNDAY) {
1199 weekDay = WeekDay.SU;
1200 }
1201 else if (dayOfWeek == Calendar.MONDAY) {
1202 weekDay = WeekDay.MO;
1203 }
1204 else if (dayOfWeek == Calendar.TUESDAY) {
1205 weekDay = WeekDay.TU;
1206 }
1207 else if (dayOfWeek == Calendar.WEDNESDAY) {
1208 weekDay = WeekDay.WE;
1209 }
1210 else if (dayOfWeek == Calendar.THURSDAY) {
1211 weekDay = WeekDay.TH;
1212 }
1213 else if (dayOfWeek == Calendar.FRIDAY) {
1214 weekDay = WeekDay.FR;
1215 }
1216 else if (dayOfWeek == Calendar.SATURDAY) {
1217 weekDay = WeekDay.SA;
1218 }
1219
1220 return weekDay;
1221 }
1222
1223 protected TimeZone toTimeZone(long userId, VTimeZone vTimeZone)
1224 throws SystemException, NoSuchUserException {
1225
1226 User user = UserUtil.findByPrimaryKey(userId);
1227
1228 TimeZone timeZone = user.getTimeZone();
1229
1230 timeZone = TimeZone.getTimeZone(
1231 vTimeZone.getTimeZoneId().getValue());
1232
1233 return timeZone;
1234 }
1235
1236 protected Recurrence toRecurrence(
1237 Recur recur, TimeZone timeZone, Calendar startDate) {
1238
1239 Calendar recStartCal = CalendarFactoryUtil.getCalendar(timeZone);
1240
1241 recStartCal.setTime(startDate.getTime());
1242
1243 Recurrence recurrence = new Recurrence(
1244 recStartCal,
1245 new com.liferay.portal.kernel.cal.Duration(1, 0, 0, 0));
1246
1247 recurrence.setWeekStart(Calendar.SUNDAY);
1248
1249 if (recur.getInterval() > 1){
1250 recurrence.setInterval(recur.getInterval());
1251 }
1252
1253 Calendar until = Calendar.getInstance(timeZone);
1254
1255 if (recur.getUntil() != null) {
1256 until.setTime(recur.getUntil());
1257
1258 recurrence.setUntil(until);
1259 }
1260
1261 String frequency = recur.getFrequency();
1262
1263 if (Recur.DAILY.equals(frequency)) {
1264 recurrence.setFrequency(Recurrence.DAILY);
1265
1266 List dayPosList = new ArrayList();
1267
1268 Iterator itr = recur.getDayList().iterator();
1269
1270 while (itr.hasNext()) {
1271 WeekDay weekDay = (WeekDay)itr.next();
1272
1273 dayPosList.add(
1274 new DayAndPosition(toCalendarWeekDay(weekDay), 0));
1275 }
1276
1277 if (!dayPosList.isEmpty()) {
1278 recurrence.setByDay(
1279 (DayAndPosition[])dayPosList.toArray(
1280 new DayAndPosition[0]));
1281 }
1282 }
1283 else if (Recur.WEEKLY.equals(frequency)) {
1284 recurrence.setFrequency(Recurrence.WEEKLY);
1285
1286 List dayPosList = new ArrayList();
1287
1288 Iterator itr = recur.getDayList().iterator();
1289
1290 while (itr.hasNext()) {
1291 WeekDay weekDay = (WeekDay)itr.next();
1292
1293 dayPosList.add(
1294 new DayAndPosition(toCalendarWeekDay(weekDay), 0));
1295 }
1296
1297 if (!dayPosList.isEmpty()) {
1298 recurrence.setByDay(
1299 (DayAndPosition[])dayPosList.toArray(
1300 new DayAndPosition[0]));
1301 }
1302 }
1303 else if (Recur.MONTHLY.equals(frequency)) {
1304 recurrence.setFrequency(Recurrence.MONTHLY);
1305
1306 Iterator itr = recur.getMonthDayList().iterator();
1307
1308 if (itr.hasNext()) {
1309 Integer monthDay = (Integer)itr.next();
1310
1311 recurrence.setByMonthDay(new int[] {monthDay.intValue()});
1312 }
1313
1314 itr = recur.getDayList().iterator();
1315
1316 if (itr.hasNext()) {
1317 WeekDay weekDay = (WeekDay)itr.next();
1318
1319 DayAndPosition[] dayPos = {
1320 new DayAndPosition(toCalendarWeekDay(weekDay),
1321 weekDay.getOffset())
1322 };
1323
1324 recurrence.setByDay(dayPos);
1325 }
1326 }
1327 else if (Recur.YEARLY.equals(frequency)) {
1328 recurrence.setFrequency(Recurrence.YEARLY);
1329 }
1330
1331 return recurrence;
1332 }
1333
1334 protected void validate(
1335 String title, int startDateMonth, int startDateDay,
1336 int startDateYear, int endDateMonth, int endDateDay,
1337 int endDateYear, int durationHour, int durationMinute,
1338 boolean allDay)
1339 throws PortalException, SystemException {
1340
1341 if (Validator.isNull(title)) {
1342 throw new EventTitleException();
1343 }
1344 else if (!Validator.isDate(
1345 startDateMonth, startDateDay, startDateYear)) {
1346
1347 throw new EventStartDateException();
1348 }
1349 else if (!Validator.isDate(endDateMonth, endDateDay, endDateYear)) {
1350 throw new EventEndDateException();
1351 }
1352
1353 if (!allDay && durationHour <= 0 && durationMinute <= 0) {
1354 throw new EventDurationException();
1355 }
1356
1357 Calendar startDate = CalendarFactoryUtil.getCalendar(
1358 startDateYear, startDateMonth, startDateDay);
1359
1360 Calendar endDate = CalendarFactoryUtil.getCalendar(
1361 endDateYear, endDateMonth, endDateDay);
1362
1363 if (startDate.after(endDate)) {
1364 throw new EventEndDateException();
1365 }
1366 }
1367
1368 private static Log _log = LogFactory.getLog(CalEventLocalServiceImpl.class);
1369
1370}