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