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