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