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