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