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