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