1
22
23 package com.liferay.portlet.calendar.service.impl;
24
25 import com.liferay.portal.PortalException;
26 import com.liferay.portal.SystemException;
27 import com.liferay.portal.im.AIMConnector;
28 import com.liferay.portal.im.ICQConnector;
29 import com.liferay.portal.im.MSNConnector;
30 import com.liferay.portal.im.YMConnector;
31 import com.liferay.portal.kernel.cal.DayAndPosition;
32 import com.liferay.portal.kernel.cal.Recurrence;
33 import com.liferay.portal.kernel.cal.TZSRecurrence;
34 import com.liferay.portal.kernel.log.Log;
35 import com.liferay.portal.kernel.log.LogFactoryUtil;
36 import com.liferay.portal.kernel.mail.MailMessage;
37 import com.liferay.portal.kernel.search.BooleanClauseOccur;
38 import com.liferay.portal.kernel.search.BooleanQuery;
39 import com.liferay.portal.kernel.search.BooleanQueryFactoryUtil;
40 import com.liferay.portal.kernel.search.Field;
41 import com.liferay.portal.kernel.search.Hits;
42 import com.liferay.portal.kernel.search.SearchEngineUtil;
43 import com.liferay.portal.kernel.search.SearchException;
44 import com.liferay.portal.kernel.util.ArrayUtil;
45 import com.liferay.portal.kernel.util.CalendarFactoryUtil;
46 import com.liferay.portal.kernel.util.CalendarUtil;
47 import com.liferay.portal.kernel.util.DateFormats;
48 import com.liferay.portal.kernel.util.GetterUtil;
49 import com.liferay.portal.kernel.util.LocaleUtil;
50 import com.liferay.portal.kernel.util.ReleaseInfo;
51 import com.liferay.portal.kernel.util.StringPool;
52 import com.liferay.portal.kernel.util.StringUtil;
53 import com.liferay.portal.kernel.util.Time;
54 import com.liferay.portal.kernel.util.TimeZoneUtil;
55 import com.liferay.portal.kernel.util.UnmodifiableList;
56 import com.liferay.portal.kernel.util.Validator;
57 import com.liferay.portal.kernel.uuid.PortalUUIDUtil;
58 import com.liferay.portal.model.Company;
59 import com.liferay.portal.model.Contact;
60 import com.liferay.portal.model.ModelHintsUtil;
61 import com.liferay.portal.model.ResourceConstants;
62 import com.liferay.portal.model.User;
63 import com.liferay.portal.service.ServiceContext;
64 import com.liferay.portal.util.PortalUtil;
65 import com.liferay.portal.util.PortletKeys;
66 import com.liferay.portlet.calendar.EventDurationException;
67 import com.liferay.portlet.calendar.EventEndDateException;
68 import com.liferay.portlet.calendar.EventStartDateException;
69 import com.liferay.portlet.calendar.EventTitleException;
70 import com.liferay.portlet.calendar.job.CheckEventJob;
71 import com.liferay.portlet.calendar.model.CalEvent;
72 import com.liferay.portlet.calendar.model.impl.CalEventImpl;
73 import com.liferay.portlet.calendar.service.base.CalEventLocalServiceBaseImpl;
74 import com.liferay.portlet.calendar.social.CalendarActivityKeys;
75 import com.liferay.portlet.calendar.util.CalUtil;
76 import com.liferay.portlet.calendar.util.Indexer;
77 import com.liferay.portlet.expando.model.ExpandoBridge;
78 import com.liferay.util.TimeZoneSensitive;
79 import com.liferay.util.servlet.ServletResponseUtil;
80
81 import java.io.BufferedOutputStream;
82 import java.io.File;
83 import java.io.FileOutputStream;
84 import java.io.FileReader;
85 import java.io.IOException;
86 import java.io.OutputStream;
87
88 import java.text.DateFormat;
89
90 import java.util.ArrayList;
91 import java.util.Calendar;
92 import java.util.Date;
93 import java.util.Iterator;
94 import java.util.List;
95 import java.util.Locale;
96 import java.util.Map;
97 import java.util.TimeZone;
98
99 import javax.mail.internet.InternetAddress;
100
101 import javax.portlet.PortletPreferences;
102
103 import net.fortuna.ical4j.data.CalendarBuilder;
104 import net.fortuna.ical4j.data.CalendarOutputter;
105 import net.fortuna.ical4j.data.ParserException;
106 import net.fortuna.ical4j.model.Component;
107 import net.fortuna.ical4j.model.DateTime;
108 import net.fortuna.ical4j.model.Dur;
109 import net.fortuna.ical4j.model.Parameter;
110 import net.fortuna.ical4j.model.Property;
111 import net.fortuna.ical4j.model.PropertyList;
112 import net.fortuna.ical4j.model.Recur;
113 import net.fortuna.ical4j.model.WeekDay;
114 import net.fortuna.ical4j.model.component.VEvent;
115 import net.fortuna.ical4j.model.parameter.Value;
116 import net.fortuna.ical4j.model.property.CalScale;
117 import net.fortuna.ical4j.model.property.Comment;
118 import net.fortuna.ical4j.model.property.DateProperty;
119 import net.fortuna.ical4j.model.property.Description;
120 import net.fortuna.ical4j.model.property.DtEnd;
121 import net.fortuna.ical4j.model.property.DtStart;
122 import net.fortuna.ical4j.model.property.Duration;
123 import net.fortuna.ical4j.model.property.ProdId;
124 import net.fortuna.ical4j.model.property.RRule;
125 import net.fortuna.ical4j.model.property.Summary;
126 import net.fortuna.ical4j.model.property.Uid;
127 import net.fortuna.ical4j.model.property.Version;
128
129
139 public class CalEventLocalServiceImpl extends CalEventLocalServiceBaseImpl {
140
141 public CalEvent addEvent(
142 long userId, String title, String description, int startDateMonth,
143 int startDateDay, int startDateYear, int startDateHour,
144 int startDateMinute, int endDateMonth, int endDateDay,
145 int endDateYear, int durationHour, int durationMinute,
146 boolean allDay, boolean timeZoneSensitive, String type,
147 boolean repeating, TZSRecurrence recurrence, int remindBy,
148 int firstReminder, int secondReminder,
149 ServiceContext serviceContext)
150 throws PortalException, SystemException {
151
152 return addEvent(
153 null, userId, title, description, startDateMonth, startDateDay,
154 startDateYear, startDateHour, startDateMinute, endDateMonth,
155 endDateDay, endDateYear, durationHour, durationMinute, allDay,
156 timeZoneSensitive, type, repeating, recurrence, remindBy,
157 firstReminder, secondReminder, serviceContext);
158 }
159
160 public CalEvent addEvent(
161 String uuid, long userId, String title, String description,
162 int startDateMonth, int startDateDay, int startDateYear,
163 int startDateHour, int startDateMinute, int endDateMonth,
164 int endDateDay, int endDateYear, int durationHour,
165 int durationMinute, boolean allDay, boolean timeZoneSensitive,
166 String type, boolean repeating, TZSRecurrence recurrence,
167 int remindBy, int firstReminder, int secondReminder,
168 ServiceContext serviceContext)
169 throws PortalException, SystemException {
170
171
173 User user = userPersistence.findByPrimaryKey(userId);
174 long groupId = serviceContext.getScopeGroupId();
175 Date now = new Date();
176
177 Locale locale = null;
178 TimeZone timeZone = null;
179
180 if (timeZoneSensitive) {
181 locale = user.getLocale();
182 timeZone = user.getTimeZone();
183 }
184 else {
185 locale = LocaleUtil.getDefault();
186 timeZone = TimeZoneUtil.getDefault();
187 }
188
189 Calendar startDate = CalendarFactoryUtil.getCalendar(timeZone, locale);
190
191 startDate.set(Calendar.MONTH, startDateMonth);
192 startDate.set(Calendar.DATE, startDateDay);
193 startDate.set(Calendar.YEAR, startDateYear);
194 startDate.set(Calendar.HOUR_OF_DAY, startDateHour);
195 startDate.set(Calendar.MINUTE, startDateMinute);
196 startDate.set(Calendar.SECOND, 0);
197 startDate.set(Calendar.MILLISECOND, 0);
198
199 Calendar endDate = CalendarFactoryUtil.getCalendar(timeZone, locale);
200
201 endDate.set(Calendar.MONTH, endDateMonth);
202 endDate.set(Calendar.DATE, endDateDay);
203 endDate.set(Calendar.YEAR, endDateYear);
204 endDate.set(Calendar.HOUR_OF_DAY, 23);
205 endDate.set(Calendar.MINUTE, 59);
206 endDate.set(Calendar.SECOND, 59);
207 endDate.set(Calendar.MILLISECOND, 999);
208
209 if (allDay) {
210 startDate.set(Calendar.HOUR_OF_DAY, 0);
211 startDate.set(Calendar.MINUTE, 0);
212
213 durationHour = 24;
214 durationMinute = 0;
215 }
216
217 validate(
218 title, startDateMonth, startDateDay, startDateYear, endDateMonth,
219 endDateDay, endDateYear, durationHour, durationMinute, allDay,
220 repeating);
221
222 long eventId = counterLocalService.increment();
223
224 CalEvent event = calEventPersistence.create(eventId);
225
226 event.setUuid(uuid);
227 event.setGroupId(groupId);
228 event.setCompanyId(user.getCompanyId());
229 event.setUserId(user.getUserId());
230 event.setUserName(user.getFullName());
231 event.setCreateDate(now);
232 event.setModifiedDate(now);
233 event.setTitle(title);
234 event.setDescription(description);
235 event.setStartDate(startDate.getTime());
236 event.setEndDate(endDate.getTime());
237 event.setDurationHour(durationHour);
238 event.setDurationMinute(durationMinute);
239 event.setAllDay(allDay);
240 event.setTimeZoneSensitive(timeZoneSensitive);
241 event.setType(type);
242 event.setRepeating(repeating);
243 event.setRecurrenceObj(recurrence);
244 event.setRemindBy(remindBy);
245 event.setFirstReminder(firstReminder);
246 event.setSecondReminder(secondReminder);
247
248 calEventPersistence.update(event, false);
249
250
252 if (serviceContext.getAddCommunityPermissions() ||
253 serviceContext.getAddGuestPermissions()) {
254
255 addEventResources(
256 event, serviceContext.getAddCommunityPermissions(),
257 serviceContext.getAddGuestPermissions());
258 }
259 else {
260 addEventResources(
261 event, serviceContext.getCommunityPermissions(),
262 serviceContext.getGuestPermissions());
263 }
264
265
267 ExpandoBridge expandoBridge = event.getExpandoBridge();
268
269 expandoBridge.setAttributes(serviceContext);
270
271
273 socialActivityLocalService.addActivity(
274 userId, groupId, CalEvent.class.getName(), eventId,
275 CalendarActivityKeys.ADD_EVENT, StringPool.BLANK, 0);
276
277
279 reIndex(event);
280
281
283 CalEventLocalUtil.clearEventsPool(event.getGroupId());
284
285 return event;
286 }
287
288 public void addEventResources(
289 long eventId, boolean addCommunityPermissions,
290 boolean addGuestPermissions)
291 throws PortalException, SystemException {
292
293 CalEvent event = calEventPersistence.findByPrimaryKey(eventId);
294
295 addEventResources(
296 event, addCommunityPermissions, addGuestPermissions);
297 }
298
299 public void addEventResources(
300 CalEvent event, boolean addCommunityPermissions,
301 boolean addGuestPermissions)
302 throws PortalException, SystemException {
303
304 resourceLocalService.addResources(
305 event.getCompanyId(), event.getGroupId(), event.getUserId(),
306 CalEvent.class.getName(), event.getEventId(), false,
307 addCommunityPermissions, addGuestPermissions);
308 }
309
310 public void addEventResources(
311 long eventId, String[] communityPermissions,
312 String[] guestPermissions)
313 throws PortalException, SystemException {
314
315 CalEvent event = calEventPersistence.findByPrimaryKey(eventId);
316
317 addEventResources(event, communityPermissions, guestPermissions);
318 }
319
320 public void addEventResources(
321 CalEvent event, String[] communityPermissions,
322 String[] guestPermissions)
323 throws PortalException, SystemException {
324
325 resourceLocalService.addModelResources(
326 event.getCompanyId(), event.getGroupId(), event.getUserId(),
327 CalEvent.class.getName(), event.getEventId(), communityPermissions,
328 guestPermissions);
329 }
330
331 public void checkEvents() throws PortalException, SystemException {
332 Iterator<CalEvent> itr = calEventPersistence.findByRemindBy(
333 CalEventImpl.REMIND_BY_NONE).iterator();
334
335 while (itr.hasNext()) {
336 CalEvent event = itr.next();
337
338 User user = userPersistence.fetchByPrimaryKey(event.getUserId());
339
340 if (user == null) {
341 deleteEvent(event);
342
343 continue;
344 }
345
346 Calendar now = CalendarFactoryUtil.getCalendar(
347 user.getTimeZone(), user.getLocale());
348
349 if (!event.isTimeZoneSensitive()) {
350 Calendar temp = CalendarFactoryUtil.getCalendar();
351
352 temp.setTime(Time.getDate(now));
353
354 now = temp;
355 }
356
357 Calendar startDate = null;
358
359 if (event.isTimeZoneSensitive()) {
360 startDate = CalendarFactoryUtil.getCalendar(
361 user.getTimeZone(), user.getLocale());
362 }
363 else {
364 startDate = CalendarFactoryUtil.getCalendar();
365 }
366
367 if (event.isRepeating()) {
368 double daysToCheck = Math.ceil(
369 CalEventImpl.REMINDERS[CalEventImpl.REMINDERS.length - 1] /
370 Time.DAY);
371
372 Calendar cal = (Calendar)now.clone();
373
374 for (int i = 0; i <= daysToCheck; i++) {
375 Recurrence recurrence = event.getRecurrenceObj();
376
377 Calendar tzICal = CalendarFactoryUtil.getCalendar(
378 cal.get(Calendar.YEAR), cal.get(Calendar.MONTH),
379 cal.get(Calendar.DATE));
380
381 Calendar recurrenceCal = getRecurrenceCal(
382 cal, tzICal, event);
383
384 if (recurrence.isInRecurrence(recurrenceCal)) {
385 remindUser(event, user, recurrenceCal, now);
386 }
387
388 cal.add(Calendar.DAY_OF_YEAR, 1);
389 }
390 }
391 else {
392 startDate.setTime(event.getStartDate());
393
394 remindUser(event, user, startDate, now);
395 }
396 }
397 }
398
399 public void deleteEvent(long eventId)
400 throws PortalException, SystemException {
401
402 CalEvent event = calEventPersistence.findByPrimaryKey(eventId);
403
404 deleteEvent(event);
405 }
406
407 public void deleteEvent(CalEvent event)
408 throws PortalException, SystemException {
409
410
412 CalEventLocalUtil.clearEventsPool(event.getGroupId());
413
414
416 socialActivityLocalService.deleteActivities(
417 CalEvent.class.getName(), event.getEventId());
418
419
421 expandoValueLocalService.deleteValues(
422 CalEvent.class.getName(), event.getEventId());
423
424
426 resourceLocalService.deleteResource(
427 event.getCompanyId(), CalEvent.class.getName(),
428 ResourceConstants.SCOPE_INDIVIDUAL, event.getEventId());
429
430
432 calEventPersistence.remove(event);
433 }
434
435 public void deleteEvents(long groupId)
436 throws PortalException, SystemException {
437
438 Iterator<CalEvent> itr = calEventPersistence.findByGroupId(
439 groupId).iterator();
440
441 while (itr.hasNext()) {
442 CalEvent event = itr.next();
443
444 deleteEvent(event);
445 }
446 }
447
448 public File exportEvent(long userId, long eventId)
449 throws PortalException, SystemException {
450
451 List<CalEvent> events = new ArrayList<CalEvent>();
452
453 CalEvent event = calEventPersistence.findByPrimaryKey(eventId);
454
455 events.add(event);
456
457 return exportICal4j(toICalCalendar(userId, events), null);
458 }
459
460 public File exportGroupEvents(long userId, long groupId, String fileName)
461 throws PortalException, SystemException {
462
463 List<CalEvent> events = calEventPersistence.findByGroupId(groupId);
464
465 return exportICal4j(toICalCalendar(userId, events), fileName);
466 }
467
468 public CalEvent getEvent(long eventId)
469 throws PortalException, SystemException {
470
471 return calEventPersistence.findByPrimaryKey(eventId);
472 }
473
474 public List<CalEvent> getEvents(
475 long groupId, String type, int start, int end)
476 throws SystemException {
477
478 if (Validator.isNull(type)) {
479 return calEventPersistence.findByGroupId(groupId, start, end);
480 }
481 else {
482 return calEventPersistence.findByG_T(groupId, type, start, end);
483 }
484 }
485
486 public List<CalEvent> getEvents(long groupId, Calendar cal)
487 throws SystemException {
488
489 Map<String, List<CalEvent>> eventsPool =
490 CalEventLocalUtil.getEventsPool(groupId);
491
492 String key = CalUtil.toString(cal);
493
494 List<CalEvent> events = eventsPool.get(key);
495
496 if (events == null) {
497
498
500 List<CalEvent> events1 = calEventFinder.findByG_SD(
501 groupId, CalendarUtil.getGTDate(cal),
502 CalendarUtil.getLTDate(cal), true);
503
504
506 Calendar tzICal = CalendarFactoryUtil.getCalendar(
507 cal.get(Calendar.YEAR), cal.get(Calendar.MONTH),
508 cal.get(Calendar.DATE));
509
510 List<CalEvent> events2 = calEventFinder.findByG_SD(
511 groupId, CalendarUtil.getGTDate(tzICal),
512 CalendarUtil.getLTDate(tzICal), false);
513
514
516 events = new ArrayList<CalEvent>();
517
518 events.addAll(events1);
519 events.addAll(events2);
520
521
523 Iterator<CalEvent> itr = getRepeatingEvents(groupId).iterator();
524
525 while (itr.hasNext()) {
526 CalEvent event = itr.next();
527
528 TZSRecurrence recurrence = event.getRecurrenceObj();
529
530 try {
531
532
534 if ((recurrence.getFrequency() !=
535 Recurrence.NO_RECURRENCE) &&
536 (recurrence.getInterval() <= 0)) {
537
538 recurrence.setInterval(1);
539
540 event.setRecurrenceObj(recurrence);
541
542 event = calEventPersistence.update(event, false);
543
544 recurrence = event.getRecurrenceObj();
545 }
546
547 if (recurrence.isInRecurrence(
548 getRecurrenceCal(cal, tzICal, event))) {
549
550 events.add(event);
551 }
552 }
553 catch (Exception e) {
554 _log.error(e.getMessage());
555 }
556 }
557
558 events = new UnmodifiableList<CalEvent>(events);
559
560 eventsPool.put(key, events);
561 }
562
563 return events;
564 }
565
566 public List<CalEvent> getEvents(long groupId, Calendar cal, String type)
567 throws SystemException {
568
569 List<CalEvent> events = getEvents(groupId, cal);
570
571 if (Validator.isNull(type)) {
572 return events;
573 }
574 else {
575 events = new ArrayList<CalEvent>(events);
576
577 Iterator<CalEvent> itr = events.iterator();
578
579 while (itr.hasNext()) {
580 CalEvent event = itr.next();
581
582 if (!event.getType().equals(type)) {
583 itr.remove();
584 }
585 }
586
587 return events;
588 }
589 }
590
591 public int getEventsCount(long groupId, String type)
592 throws SystemException {
593
594 if (Validator.isNull(type)) {
595 return calEventPersistence.countByGroupId(groupId);
596 }
597 else {
598 return calEventPersistence.countByG_T(groupId, type);
599 }
600 }
601
602 public List<CalEvent> getRepeatingEvents(long groupId)
603 throws SystemException {
604
605 Map<String, List<CalEvent>> eventsPool =
606 CalEventLocalUtil.getEventsPool(groupId);
607
608 String key = "recurrence";
609
610 List<CalEvent> events = eventsPool.get(key);
611
612 if (events == null) {
613 events = calEventPersistence.findByG_R(groupId, true);
614
615 events = new UnmodifiableList<CalEvent>(events);
616
617 eventsPool.put(key, events);
618 }
619
620 return events;
621 }
622
623 public boolean hasEvents(long groupId, Calendar cal)
624 throws SystemException {
625
626 return hasEvents(groupId, cal, null);
627 }
628
629 public boolean hasEvents(long groupId, Calendar cal, String type)
630 throws SystemException {
631
632 if (getEvents(groupId, cal, type).size() > 0) {
633 return true;
634 }
635 else {
636 return false;
637 }
638 }
639
640 public void importICal4j(long userId, long groupId, File file)
641 throws PortalException, SystemException {
642
643 FileReader fileReader = null;
644
645 try {
646 fileReader = new FileReader(file);
647
648 CalendarBuilder builder = new CalendarBuilder();
649
650 net.fortuna.ical4j.model.Calendar calendar = builder.build(
651 fileReader);
652
653 Iterator<VEvent> itr = calendar.getComponents(
654 Component.VEVENT).iterator();
655
656 while (itr.hasNext()) {
657 VEvent vEvent = itr.next();
658
659 importICal4j(userId, groupId, vEvent);
660 }
661 }
662 catch (IOException ioe) {
663 throw new SystemException(ioe.getMessage());
664 }
665 catch (ParserException pe) {
666 throw new SystemException(pe.getMessage());
667 }
668 finally {
669 try {
670 fileReader.close();
671 }
672 catch (IOException ioe) {
673 _log.error(ioe);
674 }
675 }
676 }
677
678 public void reIndex(long eventId) throws SystemException {
679 if (SearchEngineUtil.isIndexReadOnly()) {
680 return;
681 }
682
683 CalEvent event = calEventPersistence.fetchByPrimaryKey(eventId);
684
685 if (event == null) {
686 return;
687 }
688
689 reIndex(event);
690 }
691
692 public void reIndex(CalEvent event) throws SystemException {
693 long companyId = event.getCompanyId();
694 long groupId = event.getGroupId();
695 long userId = event.getUserId();
696 long eventId = event.getEventId();
697 String userName = event.getUserName();
698 String title = event.getTitle();
699 String description = event.getDescription();
700 Date modifiedDate = event.getModifiedDate();
701
702 String[] tagsEntries = tagsEntryLocalService.getEntryNames(
703 CalEvent.class.getName(), eventId);
704
705 ExpandoBridge expandoBridge = event.getExpandoBridge();
706
707 try {
708 Indexer.updateEvent(
709 companyId, groupId, userId, userName, eventId, title,
710 description, modifiedDate, tagsEntries, expandoBridge);
711 }
712 catch (SearchException se) {
713 _log.error("Reindexing " + eventId, se);
714 }
715 }
716
717 public void reIndex(String[] ids) throws SystemException {
718 if (SearchEngineUtil.isIndexReadOnly()) {
719 return;
720 }
721
722 long companyId = GetterUtil.getLong(ids[0]);
723
724 try {
725 reIndexEvents(companyId);
726 }
727 catch (SystemException se) {
728 throw se;
729 }
730 catch (Exception e) {
731 throw new SystemException(e);
732 }
733 }
734
735 public Hits search(
736 long companyId, long groupId, long userId, long ownerUserId,
737 String keywords, int start, int end)
738 throws SystemException {
739
740 try {
741 BooleanQuery contextQuery = BooleanQueryFactoryUtil.create();
742
743 contextQuery.addRequiredTerm(Field.PORTLET_ID, Indexer.PORTLET_ID);
744
745 if (groupId > 0) {
746 contextQuery.addRequiredTerm(Field.GROUP_ID, groupId);
747 }
748
749 if (ownerUserId > 0) {
750 contextQuery.addRequiredTerm(Field.USER_ID, ownerUserId);
751 }
752
753 BooleanQuery searchQuery = BooleanQueryFactoryUtil.create();
754
755 if (Validator.isNotNull(keywords)) {
756 searchQuery.addTerm(Field.USER_NAME, keywords);
757 searchQuery.addTerm(Field.TITLE, keywords);
758 searchQuery.addTerm(Field.DESCRIPTION, keywords);
759 searchQuery.addTerm(Field.TAGS_ENTRIES, keywords);
760 }
761
762 BooleanQuery fullQuery = BooleanQueryFactoryUtil.create();
763
764 fullQuery.add(contextQuery, BooleanClauseOccur.MUST);
765
766 if (searchQuery.clauses().size() > 0) {
767 fullQuery.add(searchQuery, BooleanClauseOccur.MUST);
768 }
769
770 return SearchEngineUtil.search(
771 companyId, groupId, userId, CalEvent.class.getName(), fullQuery,
772 start, end);
773 }
774 catch (Exception e) {
775 throw new SystemException(e);
776 }
777 }
778
779 public CalEvent updateEvent(
780 long userId, long eventId, String title, String description,
781 int startDateMonth, int startDateDay, int startDateYear,
782 int startDateHour, int startDateMinute, int endDateMonth,
783 int endDateDay, int endDateYear, int durationHour,
784 int durationMinute, boolean allDay, boolean timeZoneSensitive,
785 String type, boolean repeating, TZSRecurrence recurrence,
786 int remindBy, int firstReminder, int secondReminder,
787 ServiceContext serviceContext)
788 throws PortalException, SystemException {
789
790
792 User user = userPersistence.findByPrimaryKey(userId);
793
794 Locale locale = null;
795 TimeZone timeZone = null;
796
797 if (timeZoneSensitive) {
798 locale = user.getLocale();
799 timeZone = user.getTimeZone();
800 }
801 else {
802 locale = LocaleUtil.getDefault();
803 timeZone = TimeZoneUtil.getDefault();
804 }
805
806 Calendar startDate = CalendarFactoryUtil.getCalendar(timeZone, locale);
807
808 startDate.set(Calendar.MONTH, startDateMonth);
809 startDate.set(Calendar.DATE, startDateDay);
810 startDate.set(Calendar.YEAR, startDateYear);
811 startDate.set(Calendar.HOUR_OF_DAY, startDateHour);
812 startDate.set(Calendar.MINUTE, startDateMinute);
813 startDate.set(Calendar.SECOND, 0);
814 startDate.set(Calendar.MILLISECOND, 0);
815
816 Calendar endDate = CalendarFactoryUtil.getCalendar(timeZone, locale);
817
818 endDate.set(Calendar.MONTH, endDateMonth);
819 endDate.set(Calendar.DATE, endDateDay);
820 endDate.set(Calendar.YEAR, endDateYear);
821 endDate.set(Calendar.HOUR_OF_DAY, 23);
822 endDate.set(Calendar.MINUTE, 59);
823 endDate.set(Calendar.SECOND, 59);
824 endDate.set(Calendar.MILLISECOND, 999);
825
826 if (allDay) {
827 startDate.set(Calendar.HOUR_OF_DAY, 0);
828 startDate.set(Calendar.MINUTE, 0);
829
830 durationHour = 24;
831 durationMinute = 0;
832 }
833
834 validate(
835 title, startDateMonth, startDateDay, startDateYear, endDateMonth,
836 endDateDay, endDateYear, durationHour, durationMinute, allDay,
837 repeating);
838
839 CalEvent event = calEventPersistence.findByPrimaryKey(eventId);
840
841 event.setModifiedDate(new Date());
842 event.setTitle(title);
843 event.setDescription(description);
844 event.setStartDate(startDate.getTime());
845 event.setEndDate(endDate.getTime());
846 event.setDurationHour(durationHour);
847 event.setDurationMinute(durationMinute);
848 event.setAllDay(allDay);
849 event.setTimeZoneSensitive(timeZoneSensitive);
850 event.setType(type);
851 event.setRepeating(repeating);
852 event.setRecurrenceObj(recurrence);
853 event.setRemindBy(remindBy);
854 event.setFirstReminder(firstReminder);
855 event.setSecondReminder(secondReminder);
856
857 calEventPersistence.update(event, false);
858
859
861 ExpandoBridge expandoBridge = event.getExpandoBridge();
862
863 expandoBridge.setAttributes(serviceContext);
864
865
867 socialActivityLocalService.addActivity(
868 userId, event.getGroupId(), CalEvent.class.getName(), eventId,
869 CalendarActivityKeys.UPDATE_EVENT, StringPool.BLANK, 0);
870
871
873 reIndex(event);
874
875
877 CalEventLocalUtil.clearEventsPool(event.getGroupId());
878
879 return event;
880 }
881
882 protected File exportICal4j(
883 net.fortuna.ical4j.model.Calendar cal, String fileName)
884 throws SystemException {
885
886 OutputStream os = null;
887
888 try {
889 String extension = ".ics";
890
891 if (Validator.isNull(fileName)) {
892 fileName = "liferay.";
893 }
894 else {
895 int pos = fileName.lastIndexOf(StringPool.PERIOD);
896
897 if (pos != -1) {
898 extension = fileName.substring(pos);
899 fileName = fileName.substring(0, pos);
900 }
901 }
902
903 File file = File.createTempFile(fileName, extension);
904
905 os = new BufferedOutputStream(new FileOutputStream(file.getPath()));
906
907 CalendarOutputter calOutput = new CalendarOutputter();
908
909 if (cal.getComponents().isEmpty()) {
910 calOutput.setValidating(false);
911 }
912
913 calOutput.output(cal, os);
914
915 return file;
916 }
917 catch (Exception e) {
918 _log.error(e, e);
919
920 throw new SystemException(e);
921 }
922 finally {
923 ServletResponseUtil.cleanUp(os);
924 }
925 }
926
927 protected Calendar getRecurrenceCal(
928 Calendar cal, Calendar tzICal, CalEvent event) {
929
930 Calendar eventCal = CalendarFactoryUtil.getCalendar();
931 eventCal.setTime(event.getStartDate());
932
933 Calendar recurrenceCal = (Calendar)tzICal.clone();
934 recurrenceCal.set(
935 Calendar.HOUR_OF_DAY, eventCal.get(Calendar.HOUR_OF_DAY));
936 recurrenceCal.set(
937 Calendar.MINUTE, eventCal.get(Calendar.MINUTE));
938 recurrenceCal.set(Calendar.SECOND, 0);
939 recurrenceCal.set(Calendar.MILLISECOND, 0);
940
941 if (event.isTimeZoneSensitive()) {
942 int gmtDate = eventCal.get(Calendar.DATE);
943 long gmtMills = eventCal.getTimeInMillis();
944
945 eventCal.setTimeZone(cal.getTimeZone());
946
947 int tziDate = eventCal.get(Calendar.DATE);
948 long tziMills = Time.getDate(eventCal).getTime();
949
950 if (gmtDate != tziDate) {
951 int diffDate = 0;
952
953 if (gmtMills > tziMills) {
954 diffDate = (int)Math.ceil(
955 (double)(gmtMills - tziMills) / Time.DAY);
956 }
957 else {
958 diffDate = (int)Math.floor(
959 (double)(gmtMills - tziMills) / Time.DAY);
960 }
961
962 recurrenceCal.add(Calendar.DATE, diffDate);
963 }
964 }
965
966 return recurrenceCal;
967 }
968
969 protected void importICal4j(
970 long userId, long groupId, VEvent event)
971 throws PortalException, SystemException {
972
973 User user = userPersistence.findByPrimaryKey(userId);
974
975 TimeZone timeZone = user.getTimeZone();
976
977
979 Property timeZoneXProperty = event.getProperty(
980 TimeZoneSensitive.PROPERTY_NAME);
981
982 boolean timeZoneXPropertyValue = true;
983
984 if (Validator.isNotNull(timeZoneXProperty) &&
985 timeZoneXProperty.getValue().equals("FALSE")) {
986
987 timeZoneXPropertyValue = false;
988 }
989
990
992 String title = StringPool.BLANK;
993
994 if (event.getSummary() != null) {
995 title = ModelHintsUtil.trimString(
996 CalEvent.class.getName(), "title",
997 event.getSummary().getValue());
998 }
999
1000
1002 String description = StringPool.BLANK;
1003
1004 if (event.getDescription() != null) {
1005 description = event.getDescription().getValue();
1006 }
1007
1008
1010 DtStart dtStart = event.getStartDate();
1011
1012 Calendar startDate = toCalendar(
1013 dtStart, timeZone, timeZoneXPropertyValue);
1014
1015 startDate.setTime(dtStart.getDate());
1016
1017
1019 Calendar endDate = null;
1020
1021 DtEnd dtEnd = event.getEndDate(true);
1022
1023 RRule rrule = (RRule)event.getProperty(Property.RRULE);
1024
1025 if (Validator.isNotNull(dtEnd)) {
1026 endDate = toCalendar(dtEnd, timeZone, timeZoneXPropertyValue);
1027
1028 endDate.setTime(dtEnd.getDate());
1029 }
1030 else {
1031 endDate = (Calendar)startDate.clone();
1032 endDate.add(Calendar.DATE, 1);
1033 }
1034
1035
1037 long diffMillis = 0;
1038 long durationHours = 24;
1039 long durationMins = 0;
1040 boolean multiDayEvent = false;
1041
1042 if (Validator.isNotNull(dtEnd)) {
1043 diffMillis =
1044 dtEnd.getDate().getTime() - startDate.getTimeInMillis();
1045 durationHours = diffMillis / Time.HOUR;
1046 durationMins = (diffMillis / Time.MINUTE) - (durationHours * 60);
1047
1048 if ((durationHours > 24) ||
1049 ((durationHours == 24) && (durationMins > 0))) {
1050
1051 durationHours = 24;
1052 durationMins = 0;
1053 multiDayEvent = true;
1054 }
1055 }
1056
1057
1059 boolean allDay = false;
1060
1061 if (isICal4jDateOnly(event.getStartDate()) || multiDayEvent) {
1062 allDay = true;
1063 }
1064
1065
1067 boolean timeZoneSensitive = true;
1068
1069 if (allDay || !timeZoneXPropertyValue) {
1070 timeZoneSensitive = false;
1071 }
1072
1073
1075 String type = StringPool.BLANK;
1076
1077 Property comment = event.getProperty(Property.COMMENT);
1078
1079 if (Validator.isNotNull(comment) &&
1080 ArrayUtil.contains(CalEventImpl.TYPES, comment.getValue())) {
1081
1082 type = comment.getValue();
1083 }
1084
1085
1087 boolean repeating = false;
1088 TZSRecurrence recurrence = null;
1089
1090 if (multiDayEvent) {
1091 repeating = true;
1092
1093 Calendar recStartCal = CalendarFactoryUtil.getCalendar(timeZone);
1094
1095 recStartCal.setTime(startDate.getTime());
1096
1097 com.liferay.portal.kernel.cal.Duration duration =
1098 new com.liferay.portal.kernel.cal.Duration(1, 0, 0, 0);
1099
1100 recurrence = new TZSRecurrence(
1101 recStartCal, duration, Recurrence.DAILY);
1102
1103 Calendar until = (Calendar) startDate.clone();
1104
1105 until.setTimeInMillis(until.getTimeInMillis() + diffMillis);
1106
1107 recurrence.setUntil(until);
1108
1109 endDate = recurrence.getUntil();
1110 }
1111 else if (rrule != null) {
1112 repeating = true;
1113 recurrence = toRecurrence(rrule, timeZone, startDate);
1114
1115 if (recurrence.getUntil() != null) {
1116 endDate = recurrence.getUntil();
1117 }
1118 }
1119
1120
1122 int remindBy = CalEventImpl.REMIND_BY_NONE;
1123 int firstReminder = 300000;
1124 int secondReminder = 300000;
1125
1126
1128 ServiceContext serviceContext = new ServiceContext();
1129
1130 serviceContext.setAddCommunityPermissions(true);
1131 serviceContext.setAddGuestPermissions(true);
1132 serviceContext.setScopeGroupId(groupId);
1133
1134 addEvent(
1135 userId, title, description, startDate.get(Calendar.MONTH),
1136 startDate.get(Calendar.DAY_OF_MONTH), startDate.get(Calendar.YEAR),
1137 startDate.get(Calendar.HOUR_OF_DAY),
1138 startDate.get(Calendar.MINUTE), endDate.get(Calendar.MONTH),
1139 endDate.get(Calendar.DAY_OF_MONTH), endDate.get(Calendar.YEAR),
1140 (int)durationHours, (int)durationMins, allDay,
1141 timeZoneSensitive, type, repeating, recurrence, remindBy,
1142 firstReminder, secondReminder, serviceContext);
1143
1144 }
1145
1146 protected boolean isICal4jDateOnly(DateProperty date) {
1147 if (Validator.isNotNull(date.getParameter(Parameter.VALUE)) &&
1148 date.getParameter(Parameter.VALUE).getValue().equals("DATE")) {
1149
1150 return true;
1151 }
1152
1153 return false;
1154 }
1155
1156 protected void reIndexEvents(long companyId) throws SystemException {
1157 int count = calEventPersistence.countByCompanyId(companyId);
1158
1159 int pages = count / Indexer.DEFAULT_INTERVAL;
1160
1161 for (int i = 0; i <= pages; i++) {
1162 int start = (i * Indexer.DEFAULT_INTERVAL);
1163 int end = start + Indexer.DEFAULT_INTERVAL;
1164
1165 reIndexEvents(companyId, start, end);
1166 }
1167 }
1168
1169 protected void reIndexEvents(long companyId, int start, int end)
1170 throws SystemException {
1171
1172 List<CalEvent> events = calEventPersistence.findByCompanyId(
1173 companyId, start, end);
1174
1175 for (CalEvent event : events) {
1176 reIndex(event);
1177 }
1178 }
1179
1180 protected void remindUser(CalEvent event, User user, Calendar startDate) {
1181 int remindBy = event.getRemindBy();
1182
1183 if (remindBy == CalEventImpl.REMIND_BY_NONE) {
1184 return;
1185 }
1186
1187 try {
1188 long ownerId = event.getGroupId();
1189 int ownerType = PortletKeys.PREFS_OWNER_TYPE_GROUP;
1190 long plid = PortletKeys.PREFS_PLID_SHARED;
1191 String portletId = PortletKeys.CALENDAR;
1192
1193 PortletPreferences preferences =
1194 portletPreferencesLocalService.getPreferences(
1195 event.getCompanyId(), ownerId, ownerType, plid, portletId);
1196
1197 Company company = companyPersistence.findByPrimaryKey(
1198 user.getCompanyId());
1199
1200 Contact contact = user.getContact();
1201
1202 String portletName = PortalUtil.getPortletTitle(
1203 PortletKeys.CALENDAR, user);
1204
1205 String fromName = CalUtil.getEmailFromName(preferences);
1206 String fromAddress = CalUtil.getEmailFromAddress(preferences);
1207
1208 String toName = user.getFullName();
1209 String toAddress = user.getEmailAddress();
1210
1211 if (remindBy == CalEventImpl.REMIND_BY_SMS) {
1212 toAddress = contact.getSmsSn();
1213 }
1214
1215 String subject = CalUtil.getEmailEventReminderSubject(preferences);
1216 String body = CalUtil.getEmailEventReminderBody(preferences);
1217
1218 DateFormat dateFormatDateTime = DateFormats.getDateTime(
1219 user.getLocale(), user.getTimeZone());
1220
1221 subject = StringUtil.replace(
1222 subject,
1223 new String[] {
1224 "[$EVENT_START_DATE$]",
1225 "[$EVENT_TITLE$]",
1226 "[$FROM_ADDRESS$]",
1227 "[$FROM_NAME$]",
1228 "[$PORTAL_URL$]",
1229 "[$PORTLET_NAME$]",
1230 "[$TO_ADDRESS$]",
1231 "[$TO_NAME$]"
1232 },
1233 new String[] {
1234 dateFormatDateTime.format(startDate.getTime()),
1235 event.getTitle(),
1236 fromAddress,
1237 fromName,
1238 company.getVirtualHost(),
1239 portletName,
1240 toAddress,
1241 toName,
1242 });
1243
1244 body = StringUtil.replace(
1245 body,
1246 new String[] {
1247 "[$EVENT_START_DATE$]",
1248 "[$EVENT_TITLE$]",
1249 "[$FROM_ADDRESS$]",
1250 "[$FROM_NAME$]",
1251 "[$PORTAL_URL$]",
1252 "[$PORTLET_NAME$]",
1253 "[$TO_ADDRESS$]",
1254 "[$TO_NAME$]"
1255 },
1256 new String[] {
1257 dateFormatDateTime.format(startDate.getTime()),
1258 event.getTitle(),
1259 fromAddress,
1260 fromName,
1261 company.getVirtualHost(),
1262 portletName,
1263 toAddress,
1264 toName,
1265 });
1266
1267 if ((remindBy == CalEventImpl.REMIND_BY_EMAIL) ||
1268 (remindBy == CalEventImpl.REMIND_BY_SMS)) {
1269
1270 InternetAddress from = new InternetAddress(
1271 fromAddress, fromName);
1272
1273 InternetAddress to = new InternetAddress(toAddress, toName);
1274
1275 MailMessage message = new MailMessage(
1276 from, to, subject, body, true);
1277
1278 mailService.sendEmail(message);
1279 }
1280 else if ((remindBy == CalEventImpl.REMIND_BY_AIM) &&
1281 (Validator.isNotNull(contact.getAimSn()))) {
1282
1283 AIMConnector.send(contact.getAimSn(), body);
1284 }
1285 else if ((remindBy == CalEventImpl.REMIND_BY_ICQ) &&
1286 (Validator.isNotNull(contact.getIcqSn()))) {
1287
1288 ICQConnector.send(contact.getIcqSn(), body);
1289 }
1290 else if ((remindBy == CalEventImpl.REMIND_BY_MSN) &&
1291 (Validator.isNotNull(contact.getMsnSn()))) {
1292
1293 MSNConnector.send(contact.getMsnSn(), body);
1294 }
1295 else if ((remindBy == CalEventImpl.REMIND_BY_YM) &&
1296 (Validator.isNotNull(contact.getYmSn()))) {
1297
1298 YMConnector.send(contact.getYmSn(), body);
1299 }
1300 }
1301 catch (Exception e) {
1302 _log.error(e);
1303 }
1304 }
1305
1306 protected void remindUser(
1307 CalEvent event, User user, Calendar startDate, Calendar now) {
1308
1309 long diff =
1310 (startDate.getTime().getTime() - now.getTime().getTime()) /
1311 CheckEventJob.INTERVAL;
1312
1313 if ((diff == (event.getFirstReminder() / CheckEventJob.INTERVAL)) ||
1314 (diff ==
1315 (event.getSecondReminder() / CheckEventJob.INTERVAL))) {
1316
1317 remindUser(event, user, startDate);
1318 }
1319 }
1320
1321 protected Calendar toCalendar(
1322 DateProperty date, TimeZone timeZone, boolean timeZoneSensitive) {
1323
1324 Calendar cal = null;
1325
1326 if (isICal4jDateOnly(date)) {
1327 cal = Calendar.getInstance();
1328 }
1329 else if (!timeZoneSensitive) {
1330 cal = Calendar.getInstance(TimeZone.getTimeZone(StringPool.UTC));
1331 }
1332 else {
1333 cal = Calendar.getInstance(timeZone);
1334 }
1335
1336 return cal;
1337 }
1338
1339 protected int toCalendarWeekDay(WeekDay weekDay) {
1340 int dayOfWeeek = 0;
1341
1342 if (weekDay.getDay().equals(WeekDay.SU.getDay())) {
1343 dayOfWeeek = Calendar.SUNDAY;
1344 }
1345 else if (weekDay.getDay().equals(WeekDay.MO.getDay())) {
1346 dayOfWeeek = Calendar.MONDAY;
1347 }
1348 else if (weekDay.getDay().equals(WeekDay.TU.getDay())) {
1349 dayOfWeeek = Calendar.TUESDAY;
1350 }
1351 else if (weekDay.getDay().equals(WeekDay.WE.getDay())) {
1352 dayOfWeeek = Calendar.WEDNESDAY;
1353 }
1354 else if (weekDay.getDay().equals(WeekDay.TH.getDay())) {
1355 dayOfWeeek = Calendar.THURSDAY;
1356 }
1357 else if (weekDay.getDay().equals(WeekDay.FR.getDay())) {
1358 dayOfWeeek = Calendar.FRIDAY;
1359 }
1360 else if (weekDay.getDay().equals(WeekDay.SA.getDay())) {
1361 dayOfWeeek = Calendar.SATURDAY;
1362 }
1363
1364 return dayOfWeeek;
1365 }
1366
1367 protected net.fortuna.ical4j.model.Calendar toICalCalendar(
1368 long userId, List<CalEvent> events)
1369 throws PortalException, SystemException {
1370
1371 net.fortuna.ical4j.model.Calendar iCal =
1372 new net.fortuna.ical4j.model.Calendar();
1373
1374 ProdId prodId = new ProdId(
1375 "-//Liferay Inc//Liferay Portal " + ReleaseInfo.getVersion() +
1376 "//EN");
1377
1378 PropertyList props = iCal.getProperties();
1379
1380 props.add(prodId);
1381 props.add(Version.VERSION_2_0);
1382 props.add(CalScale.GREGORIAN);
1383
1384 User user = userPersistence.findByPrimaryKey(userId);
1385 TimeZone timeZone = user.getTimeZone();
1386
1387 List<VEvent> components = iCal.getComponents();
1388
1389 Iterator<CalEvent> itr = events.iterator();
1390
1391 while (itr.hasNext()) {
1392 CalEvent event = itr.next();
1393
1394 components.add(toICalVEvent(event, timeZone));
1395 }
1396
1397 return iCal;
1398 }
1399
1400 protected Recur toICalRecurrence(TZSRecurrence recurrence) {
1401 Recur recur = null;
1402
1403 int recurrenceType = recurrence.getFrequency();
1404
1405 int interval = recurrence.getInterval();
1406
1407 if (recurrenceType == Recurrence.DAILY) {
1408 recur = new Recur(Recur.DAILY, -1);
1409
1410 if (interval >= 1) {
1411 recur.setInterval(interval);
1412 }
1413
1414 DayAndPosition[] byDay = recurrence.getByDay();
1415
1416 if (byDay != null) {
1417 for (int i = 0; i < byDay.length; i++) {
1418 WeekDay weekDay = toICalWeekDay(byDay[i].getDayOfWeek());
1419
1420 recur.getDayList().add(weekDay);
1421 }
1422 }
1423
1424 }
1425 else if (recurrenceType == Recurrence.WEEKLY) {
1426 recur = new Recur(Recur.WEEKLY, -1);
1427
1428 recur.setInterval(interval);
1429
1430 DayAndPosition[] byDay = recurrence.getByDay();
1431
1432 if (byDay != null) {
1433 for (int i = 0; i < byDay.length; i++) {
1434 WeekDay weekDay = toICalWeekDay(byDay[i].getDayOfWeek());
1435
1436 recur.getDayList().add(weekDay);
1437 }
1438 }
1439 }
1440 else if (recurrenceType == Recurrence.MONTHLY) {
1441 recur = new Recur(Recur.MONTHLY, -1);
1442
1443 recur.setInterval(interval);
1444
1445 int[] byMonthDay = recurrence.getByMonthDay();
1446
1447 if (byMonthDay != null) {
1448 Integer monthDay = new Integer(byMonthDay[0]);
1449
1450 recur.getMonthDayList().add(monthDay);
1451 }
1452 else if (recurrence.getByDay() != null) {
1453 DayAndPosition[] byDay = recurrence.getByDay();
1454
1455 WeekDay weekDay = toICalWeekDay(byDay[0].getDayOfWeek());
1456
1457 recur.getDayList().add(weekDay);
1458
1459 Integer position = new Integer(byDay[0].getDayPosition());
1460
1461 recur.getSetPosList().add(position);
1462 }
1463 }
1464 else if (recurrenceType == Recurrence.YEARLY) {
1465 recur = new Recur(Recur.YEARLY, -1);
1466
1467 recur.setInterval(interval);
1468 }
1469
1470 Calendar until = recurrence.getUntil();
1471
1472 if (until != null) {
1473 DateTime dateTime = new DateTime(until.getTime());
1474
1475 recur.setUntil(dateTime);
1476 }
1477
1478 return recur;
1479 }
1480
1481 protected VEvent toICalVEvent(CalEvent event, TimeZone timeZone) {
1482 VEvent vEvent = new VEvent();
1483
1484 PropertyList eventProps = vEvent.getProperties();
1485
1486
1488 Uid uid = new Uid(PortalUUIDUtil.generate());
1489
1490 eventProps.add(uid);
1491
1492 if (event.isAllDay()) {
1493
1494
1496 DtStart dtStart = new DtStart(
1497 new net.fortuna.ical4j.model.Date(event.getStartDate()));
1498
1499 eventProps.add(dtStart);
1500
1501 Property dtStartProperty = eventProps.getProperty(Property.DTSTART);
1502
1503 dtStartProperty.getParameters().add(Value.DATE);
1504 }
1505 else {
1506
1507
1509 DtStart dtStart = new DtStart(new DateTime(event.getStartDate()));
1510
1511 eventProps.add(dtStart);
1512
1513
1515 Duration duration = new Duration(
1516 new Dur(
1517 0, event.getDurationHour(), event.getDurationMinute(), 0));
1518
1519 eventProps.add(duration);
1520 }
1521
1522
1524 Summary summary = new Summary(event.getTitle());
1525
1526 eventProps.add(summary);
1527
1528
1530 Description description = new Description(event.getDescription());
1531
1532 eventProps.add(description);
1533
1534
1536 Comment comment = new Comment(event.getType());
1537
1538 eventProps.add(comment);
1539
1540
1542 if (event.isRepeating()) {
1543 Recur recur = toICalRecurrence(event.getRecurrenceObj());
1544
1545 RRule rRule = new RRule(recur);
1546
1547 eventProps.add(rRule);
1548 }
1549
1550
1552 if (!event.getTimeZoneSensitive()) {
1553 eventProps.add(new TimeZoneSensitive("FALSE"));
1554 }
1555
1556 return vEvent;
1557 }
1558
1559 protected WeekDay toICalWeekDay(int dayOfWeek) {
1560 WeekDay weekDay = null;
1561
1562 if (dayOfWeek == Calendar.SUNDAY) {
1563 weekDay = WeekDay.SU;
1564 }
1565 else if (dayOfWeek == Calendar.MONDAY) {
1566 weekDay = WeekDay.MO;
1567 }
1568 else if (dayOfWeek == Calendar.TUESDAY) {
1569 weekDay = WeekDay.TU;
1570 }
1571 else if (dayOfWeek == Calendar.WEDNESDAY) {
1572 weekDay = WeekDay.WE;
1573 }
1574 else if (dayOfWeek == Calendar.THURSDAY) {
1575 weekDay = WeekDay.TH;
1576 }
1577 else if (dayOfWeek == Calendar.FRIDAY) {
1578 weekDay = WeekDay.FR;
1579 }
1580 else if (dayOfWeek == Calendar.SATURDAY) {
1581 weekDay = WeekDay.SA;
1582 }
1583
1584 return weekDay;
1585 }
1586
1587 protected TZSRecurrence toRecurrence(
1588 RRule rRule, TimeZone timeZone, Calendar startDate) {
1589
1590 Recur recur = rRule.getRecur();
1591
1592 Calendar recStartCal = CalendarFactoryUtil.getCalendar(timeZone);
1593
1594 recStartCal.setTime(startDate.getTime());
1595
1596 TZSRecurrence recurrence = new TZSRecurrence(
1597 recStartCal,
1598 new com.liferay.portal.kernel.cal.Duration(1, 0, 0, 0));
1599
1600 recurrence.setWeekStart(Calendar.SUNDAY);
1601
1602 if (recur.getInterval() > 1) {
1603 recurrence.setInterval(recur.getInterval());
1604 }
1605
1606 Calendar until = Calendar.getInstance(timeZone);
1607
1608 String frequency = recur.getFrequency();
1609
1610 if (Validator.isNotNull(recur.getUntil())) {
1611 until.setTime(recur.getUntil());
1612
1613 recurrence.setUntil(until);
1614 }
1615 else if (rRule.getValue().indexOf("COUNT") >= 0) {
1616 until.setTimeInMillis(startDate.getTimeInMillis());
1617
1618 int addField = 0;
1619
1620 if (Recur.DAILY.equals(frequency)) {
1621 addField = Calendar.DAY_OF_YEAR;
1622 }
1623 else if (Recur.WEEKLY.equals(frequency)) {
1624 addField = Calendar.WEEK_OF_YEAR;
1625 }
1626 else if (Recur.MONTHLY.equals(frequency)) {
1627 addField = Calendar.MONTH;
1628 }
1629 else if (Recur.YEARLY.equals(frequency)) {
1630 addField = Calendar.YEAR;
1631 }
1632
1633 int addAmount = recurrence.getInterval() * recur.getCount();
1634
1635 until.add(addField, addAmount);
1636 until.add(Calendar.DAY_OF_YEAR, -1);
1637
1638 recurrence.setUntil(until);
1639 }
1640
1641 if (Recur.DAILY.equals(frequency)) {
1642 recurrence.setFrequency(Recurrence.DAILY);
1643
1644 List<DayAndPosition> dayPosList = new ArrayList<DayAndPosition>();
1645
1646 Iterator<WeekDay> itr = recur.getDayList().iterator();
1647
1648 while (itr.hasNext()) {
1649 WeekDay weekDay = itr.next();
1650
1651 dayPosList.add(
1652 new DayAndPosition(toCalendarWeekDay(weekDay), 0));
1653 }
1654
1655 if (!dayPosList.isEmpty()) {
1656 recurrence.setByDay(
1657 dayPosList.toArray(new DayAndPosition[dayPosList.size()]));
1658 }
1659 }
1660 else if (Recur.WEEKLY.equals(frequency)) {
1661 recurrence.setFrequency(Recurrence.WEEKLY);
1662
1663 List<DayAndPosition> dayPosList = new ArrayList<DayAndPosition>();
1664
1665 Iterator<WeekDay> itr = recur.getDayList().iterator();
1666
1667 while (itr.hasNext()) {
1668 WeekDay weekDay = itr.next();
1669
1670 dayPosList.add(
1671 new DayAndPosition(toCalendarWeekDay(weekDay), 0));
1672 }
1673
1674 if (!dayPosList.isEmpty()) {
1675 recurrence.setByDay(
1676 dayPosList.toArray(new DayAndPosition[dayPosList.size()]));
1677 }
1678 }
1679 else if (Recur.MONTHLY.equals(frequency)) {
1680 recurrence.setFrequency(Recurrence.MONTHLY);
1681
1682 Iterator<Integer> monthDayListItr =
1683 recur.getMonthDayList().iterator();
1684
1685 if (monthDayListItr.hasNext()) {
1686 Integer monthDay = monthDayListItr.next();
1687
1688 recurrence.setByMonthDay(new int[] {monthDay.intValue()});
1689 }
1690
1691 Iterator<WeekDay> dayListItr = recur.getDayList().iterator();
1692
1693 if (dayListItr.hasNext()) {
1694 WeekDay weekDay = dayListItr.next();
1695
1696 DayAndPosition[] dayPos = {
1697 new DayAndPosition(toCalendarWeekDay(weekDay),
1698 weekDay.getOffset())
1699 };
1700
1701 recurrence.setByDay(dayPos);
1702 }
1703 }
1704 else if (Recur.YEARLY.equals(frequency)) {
1705 recurrence.setFrequency(Recurrence.YEARLY);
1706 }
1707
1708 return recurrence;
1709 }
1710
1711 protected void validate(
1712 String title, int startDateMonth, int startDateDay,
1713 int startDateYear, int endDateMonth, int endDateDay,
1714 int endDateYear, int durationHour, int durationMinute,
1715 boolean allDay, boolean repeating)
1716 throws PortalException {
1717
1718 if (Validator.isNull(title)) {
1719 throw new EventTitleException();
1720 }
1721 else if (!Validator.isDate(
1722 startDateMonth, startDateDay, startDateYear)) {
1723
1724 throw new EventStartDateException();
1725 }
1726 else if (!Validator.isDate(endDateMonth, endDateDay, endDateYear)) {
1727 throw new EventEndDateException();
1728 }
1729
1730 if (!allDay && durationHour <= 0 && durationMinute <= 0) {
1731 throw new EventDurationException();
1732 }
1733
1734 Calendar startDate = CalendarFactoryUtil.getCalendar(
1735 startDateYear, startDateMonth, startDateDay);
1736
1737 Calendar endDate = CalendarFactoryUtil.getCalendar(
1738 endDateYear, endDateMonth, endDateDay);
1739
1740 if (repeating && startDate.after(endDate)) {
1741 throw new EventEndDateException();
1742 }
1743 }
1744
1745 private static Log _log =
1746 LogFactoryUtil.getLog(CalEventLocalServiceImpl.class);
1747
1748}