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