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