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