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