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.ResourceConstants;
47 import com.liferay.portal.model.User;
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.job.CheckEventJob;
56 import com.liferay.portlet.calendar.model.CalEvent;
57 import com.liferay.portlet.calendar.model.impl.CalEventImpl;
58 import com.liferay.portlet.calendar.service.base.CalEventLocalServiceBaseImpl;
59 import com.liferay.portlet.calendar.util.CalUtil;
60 import com.liferay.util.Time;
61 import com.liferay.util.cal.CalendarUtil;
62 import com.liferay.util.servlet.ServletResponseUtil;
63
64 import java.io.BufferedOutputStream;
65 import java.io.File;
66 import java.io.FileOutputStream;
67 import java.io.FileReader;
68 import java.io.IOException;
69 import java.io.OutputStream;
70
71 import java.text.DateFormat;
72
73 import java.util.ArrayList;
74 import java.util.Calendar;
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, false);
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<CalEvent> itr = calEventFinder.findByRemindBy().iterator();
337
338 while (itr.hasNext()) {
339 CalEvent event = 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 CheckEventJob.INTERVAL;
369
370 if ((diff == (event.getFirstReminder() / CheckEventJob.INTERVAL)) ||
371 (diff ==
372 (event.getSecondReminder() / CheckEventJob.INTERVAL))) {
373
374 remindUser(event, user);
375 }
376 }
377 }
378
379 public void deleteEvent(long eventId)
380 throws PortalException, SystemException {
381
382 CalEvent event = calEventPersistence.findByPrimaryKey(eventId);
383
384 deleteEvent(event);
385 }
386
387 public void deleteEvent(CalEvent event)
388 throws PortalException, SystemException {
389
390
392 CalEventLocalUtil.clearEventsPool(event.getGroupId());
393
394
396 resourceLocalService.deleteResource(
397 event.getCompanyId(), CalEvent.class.getName(),
398 ResourceConstants.SCOPE_INDIVIDUAL, event.getEventId());
399
400
402 calEventPersistence.remove(event.getEventId());
403 }
404
405 public void deleteEvents(long groupId)
406 throws PortalException, SystemException {
407
408 Iterator<CalEvent> itr = calEventPersistence.findByGroupId(
409 groupId).iterator();
410
411 while (itr.hasNext()) {
412 CalEvent event = itr.next();
413
414 deleteEvent(event);
415 }
416 }
417
418 public File exportEvent(long userId, long eventId)
419 throws PortalException, SystemException {
420
421 List<CalEvent> events = new ArrayList<CalEvent>();
422
423 CalEvent event = calEventPersistence.findByPrimaryKey(eventId);
424
425 events.add(event);
426
427 return exportICal4j(toICalCalendar(userId, events), null);
428 }
429
430 public File exportGroupEvents(long userId, long plid, String fileName)
431 throws PortalException, SystemException {
432
433 long groupId = PortalUtil.getPortletGroupId(plid);
434
435 List<CalEvent> events = calEventPersistence.findByGroupId(groupId);
436
437 return exportICal4j(toICalCalendar(userId, events), fileName);
438 }
439
440 public CalEvent getEvent(long eventId)
441 throws PortalException, SystemException {
442
443 return calEventPersistence.findByPrimaryKey(eventId);
444 }
445
446 public List<CalEvent> getEvents(
447 long groupId, String type, int begin, int end)
448 throws SystemException {
449
450 if (Validator.isNull(type)) {
451 return calEventPersistence.findByGroupId(groupId, begin, end);
452 }
453 else {
454 return calEventPersistence.findByG_T(groupId, type, begin, end);
455 }
456 }
457
458 public List<CalEvent> getEvents(long groupId, Calendar cal)
459 throws SystemException {
460
461 Map<String, List<CalEvent>> eventsPool =
462 CalEventLocalUtil.getEventsPool(groupId);
463
464 String key = CalUtil.toString(cal);
465
466 List<CalEvent> events = eventsPool.get(key);
467
468 if (events == null) {
469
470
472 List<CalEvent> events1 = calEventFinder.findByG_SD(
473 groupId, CalendarUtil.getGTDate(cal),
474 CalendarUtil.getLTDate(cal), true);
475
476
478 Calendar tzICal = CalendarFactoryUtil.getCalendar(
479 cal.get(Calendar.YEAR),
480 cal.get(Calendar.MONTH),
481 cal.get(Calendar.DATE));
482
483 List<CalEvent> events2 = calEventFinder.findByG_SD(
484 groupId, CalendarUtil.getGTDate(tzICal),
485 CalendarUtil.getLTDate(tzICal), false);
486
487
489 events = new ArrayList<CalEvent>();
490
491 events.addAll(events1);
492 events.addAll(events2);
493
494
496 Iterator<CalEvent> itr = getRepeatingEvents(groupId).iterator();
497
498 while (itr.hasNext()) {
499 CalEvent event = itr.next();
500
501 Recurrence recurrence = event.getRecurrenceObj();
502
503 try {
504
505
507 if ((recurrence.getFrequency() == Recurrence.DAILY) &&
508 (recurrence.getInterval() <= 0)) {
509
510 recurrence.setInterval(1);
511
512 event.setRecurrence(Base64.objectToString(recurrence));
513
514 event = calEventPersistence.update(event, false);
515
516 recurrence = event.getRecurrenceObj();
517 }
518
519 if (recurrence.isInRecurrence(
520 getRecurrenceCal(cal, tzICal, event))) {
521
522 events.add(event);
523 }
524 }
525 catch (Exception e) {
526 _log.error(e.getMessage());
527 }
528 }
529
530 eventsPool.put(key, events);
531 }
532
533 return events;
534 }
535
536 public List<CalEvent> getEvents(long groupId, Calendar cal, String type)
537 throws SystemException {
538
539 List<CalEvent> events = getEvents(groupId, cal);
540
541 if (Validator.isNull(type)) {
542 return events;
543 }
544 else {
545 events = new ArrayList<CalEvent>(events);
546
547 Iterator<CalEvent> itr = events.iterator();
548
549 while (itr.hasNext()) {
550 CalEvent event = itr.next();
551
552 if (!event.getType().equals(type)) {
553 itr.remove();
554 }
555 }
556
557 return events;
558 }
559 }
560
561 public int getEventsCount(long groupId, String type)
562 throws SystemException {
563
564 if (Validator.isNull(type)) {
565 return calEventPersistence.countByGroupId(groupId);
566 }
567 else {
568 return calEventPersistence.countByG_T(groupId, type);
569 }
570 }
571
572 public List<CalEvent> getRepeatingEvents(long groupId)
573 throws SystemException {
574
575 Map<String, List<CalEvent>> eventsPool =
576 CalEventLocalUtil.getEventsPool(groupId);
577
578 String key = "recurrence";
579
580 List<CalEvent> events = eventsPool.get(key);
581
582 if (events == null) {
583 events = calEventPersistence.findByG_R(groupId, true);
584
585 eventsPool.put(key, events);
586 }
587
588 return events;
589 }
590
591 public boolean hasEvents(long groupId, Calendar cal)
592 throws SystemException {
593
594 return hasEvents(groupId, cal, null);
595 }
596
597 public boolean hasEvents(long groupId, Calendar cal, String type)
598 throws SystemException {
599
600 if (getEvents(groupId, cal, type).size() > 0) {
601 return true;
602 }
603 else {
604 return false;
605 }
606 }
607
608 public void importICal4j(long userId, long plid, File file)
609 throws PortalException, SystemException {
610
611 try {
612 CalendarBuilder builder = new CalendarBuilder();
613
614 net.fortuna.ical4j.model.Calendar calendar = builder.build(
615 new FileReader(file));
616
617 TimeZone timeZone = toTimeZone(
618 userId, (VTimeZone)calendar.getComponent(Component.VTIMEZONE));
619
620 Iterator<VEvent> itr = calendar.getComponents(
621 Component.VEVENT).iterator();
622
623 while (itr.hasNext()) {
624 VEvent vEvent = itr.next();
625
626 importICal4j(userId, plid, vEvent, timeZone);
627 }
628 }
629 catch (IOException ioe) {
630 throw new SystemException(ioe.getMessage());
631 }
632 catch (ParserException pe) {
633 throw new SystemException(pe.getMessage());
634 }
635 }
636
637 public CalEvent updateEvent(
638 long userId, long eventId, String title, String description,
639 int startDateMonth, int startDateDay, int startDateYear,
640 int startDateHour, int startDateMinute, int endDateMonth,
641 int endDateDay, int endDateYear, int durationHour,
642 int durationMinute, boolean allDay, boolean timeZoneSensitive,
643 String type, boolean repeating, Recurrence recurrence,
644 String remindBy, int firstReminder, int secondReminder)
645 throws PortalException, SystemException {
646
647 User user = userPersistence.findByPrimaryKey(userId);
648
649 Locale locale = null;
650 TimeZone timeZone = null;
651
652 if (timeZoneSensitive) {
653 locale = user.getLocale();
654 timeZone = user.getTimeZone();
655 }
656 else {
657 locale = LocaleUtil.getDefault();
658 timeZone = TimeZoneUtil.getDefault();
659 }
660
661 Calendar startDate = CalendarFactoryUtil.getCalendar(timeZone, locale);
662
663 startDate.set(Calendar.MONTH, startDateMonth);
664 startDate.set(Calendar.DATE, startDateDay);
665 startDate.set(Calendar.YEAR, startDateYear);
666 startDate.set(Calendar.HOUR_OF_DAY, startDateHour);
667 startDate.set(Calendar.MINUTE, startDateMinute);
668 startDate.set(Calendar.SECOND, 0);
669 startDate.set(Calendar.MILLISECOND, 0);
670
671 Calendar endDate = CalendarFactoryUtil.getCalendar(timeZone, locale);
672
673 endDate.set(Calendar.MONTH, endDateMonth);
674 endDate.set(Calendar.DATE, endDateDay);
675 endDate.set(Calendar.YEAR, endDateYear);
676 endDate.set(Calendar.HOUR_OF_DAY, 23);
677 endDate.set(Calendar.MINUTE, 59);
678 endDate.set(Calendar.SECOND, 59);
679 endDate.set(Calendar.MILLISECOND, 999);
680
681 if (allDay) {
682 startDate.set(Calendar.HOUR_OF_DAY, 0);
683 startDate.set(Calendar.MINUTE, 0);
684
685 durationHour = 24;
686 durationMinute = 0;
687 }
688
689 validate(
690 title, startDateMonth, startDateDay, startDateYear, endDateMonth,
691 endDateDay, endDateYear, durationHour, durationMinute, allDay);
692
693 CalEvent event = calEventPersistence.findByPrimaryKey(eventId);
694
695 event.setModifiedDate(new Date());
696 event.setTitle(title);
697 event.setDescription(description);
698 event.setStartDate(startDate.getTime());
699 event.setEndDate(endDate.getTime());
700 event.setDurationHour(durationHour);
701 event.setDurationMinute(durationMinute);
702 event.setAllDay(allDay);
703 event.setTimeZoneSensitive(timeZoneSensitive);
704 event.setType(type);
705 event.setRepeating(repeating);
706 event.setRecurrence(Base64.objectToString(recurrence));
707 event.setRemindBy(remindBy);
708 event.setFirstReminder(firstReminder);
709 event.setSecondReminder(secondReminder);
710
711 calEventPersistence.update(event, false);
712
713 CalEventLocalUtil.clearEventsPool(event.getGroupId());
714
715 return event;
716 }
717
718 protected File exportICal4j(
719 net.fortuna.ical4j.model.Calendar cal, String fileName)
720 throws SystemException {
721
722 OutputStream os = null;
723
724 try {
725 String extension = ".ics";
726
727 if (Validator.isNull(fileName)) {
728 fileName = "liferay.";
729 }
730 else {
731 int pos = fileName.lastIndexOf(StringPool.PERIOD);
732
733 if (pos != -1) {
734 extension = fileName.substring(pos);
735 fileName = fileName.substring(0, pos);
736 }
737 }
738
739 File file = File.createTempFile(fileName, extension);
740
741 os = new BufferedOutputStream(new FileOutputStream(file.getPath()));
742
743 CalendarOutputter calOutput = new CalendarOutputter();
744
745 calOutput.output(cal, os);
746
747 return file;
748 }
749 catch (Exception e) {
750 _log.error(e, e);
751
752 throw new SystemException(e);
753 }
754 finally {
755 ServletResponseUtil.cleanUp(os);
756 }
757 }
758
759 protected Calendar getRecurrenceCal(
760 Calendar cal, Calendar tzICal, CalEvent event) {
761
762 Calendar eventCal = CalendarFactoryUtil.getCalendar();
763 eventCal.setTime(event.getStartDate());
764
765 Calendar recurrenceCal = (Calendar)tzICal.clone();
766 recurrenceCal.set(
767 Calendar.HOUR_OF_DAY, eventCal.get(Calendar.HOUR_OF_DAY));
768 recurrenceCal.set(
769 Calendar.MINUTE, eventCal.get(Calendar.MINUTE));
770 recurrenceCal.set(Calendar.SECOND, 0);
771 recurrenceCal.set(Calendar.MILLISECOND, 0);
772
773 if (event.isTimeZoneSensitive()) {
774 int gmtDate = eventCal.get(Calendar.DATE);
775 long gmtMills = eventCal.getTimeInMillis();
776
777 eventCal.setTimeZone(cal.getTimeZone());
778
779 int tziDate = eventCal.get(Calendar.DATE);
780 long tziMills = Time.getDate(eventCal).getTime();
781
782 if (gmtDate != tziDate) {
783 int diffDate = 0;
784
785 if (gmtMills > tziMills) {
786 diffDate = (int)Math.ceil(
787 (double)(gmtMills - tziMills) / Time.DAY);
788 }
789 else {
790 diffDate = (int)Math.floor(
791 (double)(gmtMills - tziMills) / Time.DAY);
792 }
793
794 recurrenceCal.add(Calendar.DATE, diffDate);
795 }
796 }
797
798 return recurrenceCal;
799 }
800
801 protected void importICal4j(
802 long userId, long plid, VEvent event, TimeZone timeZone)
803 throws PortalException, SystemException {
804
805 String title = StringPool.BLANK;
806
807 if (event.getSummary() != null) {
808 title = event.getSummary().getValue();
809 }
810
811 String description = StringPool.BLANK;
812
813 if (event.getDescription() != null) {
814 description = event.getDescription().getValue();
815 }
816
817 Calendar startDate = Calendar.getInstance(timeZone);
818
819 startDate.setTime(event.getStartDate().getDate());
820
821 Calendar endDate = Calendar.getInstance(timeZone);
822
823 endDate.setTime(event.getEndDate().getDate());
824
825 long diffMillis =
826 endDate.getTimeInMillis() - startDate.getTimeInMillis();
827 long durationHours = diffMillis / (60 * 60 * 1000);
828 long durationMins =
829 (diffMillis / (60 * 1000)) - (durationHours * 60);
830 boolean allDay = false;
831
832 if (event.getProperty(Property.DTSTART).getParameter(
833 Parameter.TZID) == null){
834
835 Calendar startDateWithoutTimeZone = Calendar.getInstance();
836
837 startDateWithoutTimeZone.setTime(
838 event.getStartDate().getDate());
839
840 startDate.set(
841 Calendar.DAY_OF_MONTH,
842 startDateWithoutTimeZone.get(Calendar.DAY_OF_MONTH));
843 startDate.set(Calendar.HOUR_OF_DAY, 0);
844 startDate.set(Calendar.MINUTE, 0);
845 startDate.set(Calendar.SECOND, 0);
846 startDate.set(Calendar.MILLISECOND, 0);
847
848 durationHours = 24;
849 durationMins = 0;
850 allDay = true;
851 }
852
853 boolean timeZoneSensitive = false;
854 String type = StringPool.BLANK;
855 boolean repeating = false;
856 Recurrence recurrence = null;
857
858 RRule rrule = (RRule)event.getProperty(Property.RRULE);
859
860 if (rrule != null) {
861 repeating = true;
862 recurrence = toRecurrence(
863 rrule.getRecur(), timeZone, startDate);
864
865 if (recurrence.getUntil() != null) {
866 endDate = recurrence.getUntil();
867 }
868 }
869
870 String remindBy = "none";
871 int firstReminder = 300000;
872 int secondReminder = 300000;
873
874 boolean addCommunityPermissions = false;
875 boolean addGuestPermissions = false;
876
877 addEvent(
878 userId, plid, title, description, startDate.get(Calendar.MONTH),
879 startDate.get(Calendar.DAY_OF_MONTH),
880 startDate.get(Calendar.YEAR),
881 startDate.get(Calendar.HOUR_OF_DAY),
882 startDate.get(Calendar.MINUTE), endDate.get(Calendar.MONTH),
883 endDate.get(Calendar.DAY_OF_MONTH), endDate.get(Calendar.YEAR),
884 (int)durationHours, (int)durationMins, allDay,
885 timeZoneSensitive, type, repeating, recurrence, remindBy,
886 firstReminder, secondReminder, addCommunityPermissions,
887 addGuestPermissions);
888
889 }
890
891 protected void remindUser(CalEvent event, User user) {
892 String remindBy = event.getRemindBy();
893
894 if (remindBy.equals(CalEventImpl.REMIND_BY_NONE)) {
895 return;
896 }
897
898 try {
899 long ownerId = event.getGroupId();
900 int ownerType = PortletKeys.PREFS_OWNER_TYPE_GROUP;
901 long plid = PortletKeys.PREFS_PLID_SHARED;
902 String portletId = PortletKeys.CALENDAR;
903
904 PortletPreferences prefs =
905 portletPreferencesLocalService.getPreferences(
906 event.getCompanyId(), ownerId, ownerType, plid, portletId);
907
908 Company company = companyPersistence.findByPrimaryKey(
909 user.getCompanyId());
910
911 Contact contact = user.getContact();
912
913 String portletName = PortalUtil.getPortletTitle(
914 PortletKeys.CALENDAR, user);
915
916 String fromName = CalUtil.getEmailFromName(prefs);
917 String fromAddress = CalUtil.getEmailFromAddress(prefs);
918
919 String toName = user.getFullName();
920 String toAddress = user.getEmailAddress();
921
922 if (remindBy.equals(CalEventImpl.REMIND_BY_SMS)) {
923 toAddress = contact.getSmsSn();
924 }
925
926 String subject = CalUtil.getEmailEventReminderSubject(prefs);
927 String body = CalUtil.getEmailEventReminderBody(prefs);
928
929 DateFormat dateFormatDateTime = DateFormats.getDateTime(
930 user.getLocale(), user.getTimeZone());
931
932 subject = StringUtil.replace(
933 subject,
934 new String[] {
935 "[$EVENT_START_DATE$]",
936 "[$EVENT_TITLE$]",
937 "[$FROM_ADDRESS$]",
938 "[$FROM_NAME$]",
939 "[$PORTAL_URL$]",
940 "[$PORTLET_NAME$]",
941 "[$TO_ADDRESS$]",
942 "[$TO_NAME$]"
943 },
944 new String[] {
945 dateFormatDateTime.format(event.getStartDate()),
946 event.getTitle(),
947 fromAddress,
948 fromName,
949 company.getVirtualHost(),
950 portletName,
951 toAddress,
952 toName,
953 });
954
955 body = StringUtil.replace(
956 body,
957 new String[] {
958 "[$EVENT_START_DATE$]",
959 "[$EVENT_TITLE$]",
960 "[$FROM_ADDRESS$]",
961 "[$FROM_NAME$]",
962 "[$PORTAL_URL$]",
963 "[$PORTLET_NAME$]",
964 "[$TO_ADDRESS$]",
965 "[$TO_NAME$]"
966 },
967 new String[] {
968 dateFormatDateTime.format(event.getStartDate()),
969 event.getTitle(),
970 fromAddress,
971 fromName,
972 company.getVirtualHost(),
973 portletName,
974 toAddress,
975 toName,
976 });
977
978 if (remindBy.equals(CalEventImpl.REMIND_BY_EMAIL) ||
979 remindBy.equals(CalEventImpl.REMIND_BY_SMS)) {
980
981 InternetAddress from = new InternetAddress(
982 fromAddress, fromName);
983
984 InternetAddress to = new InternetAddress(toAddress, toName);
985
986 MailMessage message = new MailMessage(
987 from, to, subject, body, true);
988
989 mailService.sendEmail(message);
990 }
991 else if (remindBy.equals(CalEventImpl.REMIND_BY_AIM) &&
992 Validator.isNotNull(contact.getAimSn())) {
993
994 AIMConnector.send(contact.getAimSn(), body);
995 }
996 else if (remindBy.equals(CalEventImpl.REMIND_BY_ICQ) &&
997 Validator.isNotNull(contact.getIcqSn())) {
998
999 ICQConnector.send(contact.getIcqSn(), body);
1000 }
1001 else if (remindBy.equals(CalEventImpl.REMIND_BY_MSN) &&
1002 Validator.isNotNull(contact.getMsnSn())) {
1003
1004 MSNConnector.send(contact.getMsnSn(), body);
1005 }
1006 else if (remindBy.equals(CalEventImpl.REMIND_BY_YM) &&
1007 Validator.isNotNull(contact.getYmSn())) {
1008
1009 YMConnector.send(contact.getYmSn(), body);
1010 }
1011 }
1012 catch (Exception e) {
1013 _log.error(e);
1014 }
1015 }
1016
1017 protected int toCalendarWeekDay(WeekDay weekDay) {
1018 int dayOfWeeek = 0;
1019
1020 if (weekDay.getDay().equals(WeekDay.SU.getDay())) {
1021 dayOfWeeek = Calendar.SUNDAY;
1022 }
1023 else if (weekDay.getDay().equals(WeekDay.MO.getDay())) {
1024 dayOfWeeek = Calendar.MONDAY;
1025 }
1026 else if (weekDay.getDay().equals(WeekDay.TU.getDay())) {
1027 dayOfWeeek = Calendar.TUESDAY;
1028 }
1029 else if (weekDay.getDay().equals(WeekDay.WE.getDay())) {
1030 dayOfWeeek = Calendar.WEDNESDAY;
1031 }
1032 else if (weekDay.getDay().equals(WeekDay.TH.getDay())) {
1033 dayOfWeeek = Calendar.THURSDAY;
1034 }
1035 else if (weekDay.getDay().equals(WeekDay.FR.getDay())) {
1036 dayOfWeeek = Calendar.FRIDAY;
1037 }
1038 else if (weekDay.getDay().equals(WeekDay.SA.getDay())) {
1039 dayOfWeeek = Calendar.SATURDAY;
1040 }
1041
1042 return dayOfWeeek;
1043 }
1044
1045 protected net.fortuna.ical4j.model.Calendar toICalCalendar(
1046 long userId, List<CalEvent> events)
1047 throws PortalException, SystemException {
1048
1049 net.fortuna.ical4j.model.Calendar iCal =
1050 new net.fortuna.ical4j.model.Calendar();
1051
1052 ProdId prodId = new ProdId(
1053 "-//Liferay Inc//Liferay Portal " + ReleaseInfo.getVersion() +
1054 "//EN");
1055
1056 PropertyList props = iCal.getProperties();
1057
1058 props.add(prodId);
1059 props.add(Version.VERSION_2_0);
1060 props.add(CalScale.GREGORIAN);
1061
1062 User user = userPersistence.findByPrimaryKey(userId);
1063 TimeZone timeZone = user.getTimeZone();
1064
1065 List<VEvent> components = iCal.getComponents();
1066
1067 Iterator<CalEvent> itr = events.iterator();
1068
1069 while (itr.hasNext()) {
1070 CalEvent event = itr.next();
1071
1072 components.add(toICalVEvent(event, timeZone));
1073 }
1074
1075 return iCal;
1076 }
1077
1078 protected Recur toICalRecurrence(Recurrence recurrence) {
1079 Recur recur = null;
1080
1081 int recurrenceType = recurrence.getFrequency();
1082
1083 int interval = recurrence.getInterval();
1084
1085 if (recurrenceType == Recurrence.DAILY) {
1086 recur = new Recur(Recur.DAILY, -1);
1087
1088 if (interval >= 1) {
1089 recur.setInterval(interval);
1090 }
1091
1092 DayAndPosition[] byDay = recurrence.getByDay();
1093
1094 if (byDay != null) {
1095 for (int i = 0; i < byDay.length; i++) {
1096 WeekDay weekDay = toICalWeekDay(byDay[i].getDayOfWeek());
1097
1098 recur.getDayList().add(weekDay);
1099 }
1100 }
1101
1102 }
1103 else if (recurrenceType == Recurrence.WEEKLY) {
1104 recur = new Recur(Recur.WEEKLY, -1);
1105
1106 recur.setInterval(interval);
1107
1108 DayAndPosition[] byDay = recurrence.getByDay();
1109
1110 if (byDay != null) {
1111 for (int i = 0; i < byDay.length; i++) {
1112 WeekDay weekDay = toICalWeekDay(byDay[i].getDayOfWeek());
1113
1114 recur.getDayList().add(weekDay);
1115 }
1116 }
1117 }
1118 else if (recurrenceType == Recurrence.MONTHLY) {
1119 recur = new Recur(Recur.MONTHLY, -1);
1120
1121 recur.setInterval(interval);
1122
1123 int[] byMonthDay = recurrence.getByMonthDay();
1124
1125 if (byMonthDay != null) {
1126 Integer monthDay = new Integer(byMonthDay[0]);
1127
1128 recur.getMonthDayList().add(monthDay);
1129 }
1130 else if (recurrence.getByDay() != null){
1131 DayAndPosition[] byDay = recurrence.getByDay();
1132
1133 WeekDay weekDay = toICalWeekDay(byDay[0].getDayOfWeek());
1134
1135 recur.getDayList().add(weekDay);
1136
1137 Integer position = new Integer(byDay[0].getDayPosition());
1138
1139 recur.getSetPosList().add(position);
1140 }
1141 }
1142 else if (recurrenceType == Recurrence.YEARLY) {
1143 recur = new Recur(Recur.YEARLY, -1);
1144
1145 recur.setInterval(interval);
1146 }
1147
1148 Calendar until = recurrence.getUntil();
1149
1150 if (until != null) {
1151 DateTime dateTime = new DateTime(until.getTime());
1152
1153 recur.setUntil(dateTime);
1154 }
1155
1156 return recur;
1157 }
1158
1159 protected VEvent toICalVEvent(CalEvent event, TimeZone timeZone){
1160 VEvent vEvent = new VEvent();
1161
1162 PropertyList eventProps = vEvent.getProperties();
1163
1164
1166 Uid uid = new Uid(PortalUUIDUtil.generate());
1167
1168 eventProps.add(uid);
1169
1170 DtStart dtStart = new DtStart(new DateTime(event.getStartDate()));
1171
1172 eventProps.add(dtStart);
1173
1174
1176 Calendar cal = Calendar.getInstance();
1177
1178 Date start = cal.getTime();
1179
1180 cal.add(Calendar.HOUR, event.getDurationHour());
1181 cal.add(Calendar.MINUTE, event.getDurationHour());
1182
1183 Date end = cal.getTime();
1184
1185 Duration duration = new Duration(start, end);
1186
1187 eventProps.add(duration);
1188
1189
1191 Summary summary = new Summary(event.getTitle());
1192
1193 eventProps.add(summary);
1194
1195
1197 Description description = new Description(event.getDescription());
1198
1199 eventProps.add(description);
1200
1201
1203 Comment comment = new Comment(event.getType());
1204
1205 eventProps.add(comment);
1206
1207
1209 if (event.isRepeating()) {
1210 Recur recur = toICalRecurrence(event.getRecurrenceObj());
1211
1212 RRule rRule = new RRule(recur);
1213
1214 eventProps.add(rRule);
1215 }
1216
1217 return vEvent;
1218 }
1219
1220 protected WeekDay toICalWeekDay(int dayOfWeek) {
1221 WeekDay weekDay = null;
1222
1223 if (dayOfWeek == Calendar.SUNDAY) {
1224 weekDay = WeekDay.SU;
1225 }
1226 else if (dayOfWeek == Calendar.MONDAY) {
1227 weekDay = WeekDay.MO;
1228 }
1229 else if (dayOfWeek == Calendar.TUESDAY) {
1230 weekDay = WeekDay.TU;
1231 }
1232 else if (dayOfWeek == Calendar.WEDNESDAY) {
1233 weekDay = WeekDay.WE;
1234 }
1235 else if (dayOfWeek == Calendar.THURSDAY) {
1236 weekDay = WeekDay.TH;
1237 }
1238 else if (dayOfWeek == Calendar.FRIDAY) {
1239 weekDay = WeekDay.FR;
1240 }
1241 else if (dayOfWeek == Calendar.SATURDAY) {
1242 weekDay = WeekDay.SA;
1243 }
1244
1245 return weekDay;
1246 }
1247
1248 protected TimeZone toTimeZone(long userId, VTimeZone vTimeZone)
1249 throws SystemException, NoSuchUserException {
1250
1251 User user = userPersistence.findByPrimaryKey(userId);
1252
1253 TimeZone timeZone = user.getTimeZone();
1254
1255 timeZone = TimeZone.getTimeZone(
1256 vTimeZone.getTimeZoneId().getValue());
1257
1258 return timeZone;
1259 }
1260
1261 protected Recurrence toRecurrence(
1262 Recur recur, TimeZone timeZone, Calendar startDate) {
1263
1264 Calendar recStartCal = CalendarFactoryUtil.getCalendar(timeZone);
1265
1266 recStartCal.setTime(startDate.getTime());
1267
1268 Recurrence recurrence = new Recurrence(
1269 recStartCal,
1270 new com.liferay.portal.kernel.cal.Duration(1, 0, 0, 0));
1271
1272 recurrence.setWeekStart(Calendar.SUNDAY);
1273
1274 if (recur.getInterval() > 1){
1275 recurrence.setInterval(recur.getInterval());
1276 }
1277
1278 Calendar until = Calendar.getInstance(timeZone);
1279
1280 if (recur.getUntil() != null) {
1281 until.setTime(recur.getUntil());
1282
1283 recurrence.setUntil(until);
1284 }
1285
1286 String frequency = recur.getFrequency();
1287
1288 if (Recur.DAILY.equals(frequency)) {
1289 recurrence.setFrequency(Recurrence.DAILY);
1290
1291 List<DayAndPosition> dayPosList = new ArrayList<DayAndPosition>();
1292
1293 Iterator<WeekDay> itr = recur.getDayList().iterator();
1294
1295 while (itr.hasNext()) {
1296 WeekDay weekDay = itr.next();
1297
1298 dayPosList.add(
1299 new DayAndPosition(toCalendarWeekDay(weekDay), 0));
1300 }
1301
1302 if (!dayPosList.isEmpty()) {
1303 recurrence.setByDay(
1304 dayPosList.toArray(new DayAndPosition[dayPosList.size()]));
1305 }
1306 }
1307 else if (Recur.WEEKLY.equals(frequency)) {
1308 recurrence.setFrequency(Recurrence.WEEKLY);
1309
1310 List<DayAndPosition> dayPosList = new ArrayList<DayAndPosition>();
1311
1312 Iterator<WeekDay> itr = recur.getDayList().iterator();
1313
1314 while (itr.hasNext()) {
1315 WeekDay weekDay = itr.next();
1316
1317 dayPosList.add(
1318 new DayAndPosition(toCalendarWeekDay(weekDay), 0));
1319 }
1320
1321 if (!dayPosList.isEmpty()) {
1322 recurrence.setByDay(
1323 dayPosList.toArray(new DayAndPosition[dayPosList.size()]));
1324 }
1325 }
1326 else if (Recur.MONTHLY.equals(frequency)) {
1327 recurrence.setFrequency(Recurrence.MONTHLY);
1328
1329 Iterator<Integer> monthDayListItr =
1330 recur.getMonthDayList().iterator();
1331
1332 if (monthDayListItr.hasNext()) {
1333 Integer monthDay = monthDayListItr.next();
1334
1335 recurrence.setByMonthDay(new int[] {monthDay.intValue()});
1336 }
1337
1338 Iterator<WeekDay> dayListItr = recur.getDayList().iterator();
1339
1340 if (dayListItr.hasNext()) {
1341 WeekDay weekDay = dayListItr.next();
1342
1343 DayAndPosition[] dayPos = {
1344 new DayAndPosition(toCalendarWeekDay(weekDay),
1345 weekDay.getOffset())
1346 };
1347
1348 recurrence.setByDay(dayPos);
1349 }
1350 }
1351 else if (Recur.YEARLY.equals(frequency)) {
1352 recurrence.setFrequency(Recurrence.YEARLY);
1353 }
1354
1355 return recurrence;
1356 }
1357
1358 protected void validate(
1359 String title, int startDateMonth, int startDateDay,
1360 int startDateYear, int endDateMonth, int endDateDay,
1361 int endDateYear, int durationHour, int durationMinute,
1362 boolean allDay)
1363 throws PortalException, SystemException {
1364
1365 if (Validator.isNull(title)) {
1366 throw new EventTitleException();
1367 }
1368 else if (!Validator.isDate(
1369 startDateMonth, startDateDay, startDateYear)) {
1370
1371 throw new EventStartDateException();
1372 }
1373 else if (!Validator.isDate(endDateMonth, endDateDay, endDateYear)) {
1374 throw new EventEndDateException();
1375 }
1376
1377 if (!allDay && durationHour <= 0 && durationMinute <= 0) {
1378 throw new EventDurationException();
1379 }
1380
1381 Calendar startDate = CalendarFactoryUtil.getCalendar(
1382 startDateYear, startDateMonth, startDateDay);
1383
1384 Calendar endDate = CalendarFactoryUtil.getCalendar(
1385 endDateYear, endDateMonth, endDateDay);
1386
1387 if (startDate.after(endDate)) {
1388 throw new EventEndDateException();
1389 }
1390 }
1391
1392 private static Log _log = LogFactory.getLog(CalEventLocalServiceImpl.class);
1393
1394}