@Override public void populate(Resource resource) throws LocalStorageException { Event e = (Event) resource; try { @Cleanup Cursor cursor = providerClient.query( ContentUris.withAppendedId(entriesURI(), e.getLocalID()), new String[] { /* 0 */ Events.TITLE, Events.EVENT_LOCATION, Events.DESCRIPTION, /* 3 */ Events.DTSTART, Events.DTEND, Events.EVENT_TIMEZONE, Events.EVENT_END_TIMEZONE, Events.ALL_DAY, /* 8 */ Events.STATUS, Events.ACCESS_LEVEL, /* 10 */ Events.RRULE, Events.RDATE, Events.EXRULE, Events.EXDATE, /* 14 */ Events.HAS_ATTENDEE_DATA, Events.ORGANIZER, Events.SELF_ATTENDEE_STATUS, /* 17 */ entryColumnUID(), Events.DURATION, Events.AVAILABILITY }, null, null, null); if (cursor != null && cursor.moveToNext()) { e.setUid(cursor.getString(17)); e.setSummary(cursor.getString(0)); e.setLocation(cursor.getString(1)); e.setDescription(cursor.getString(2)); boolean allDay = cursor.getInt(7) != 0; long tsStart = cursor.getLong(3), tsEnd = cursor.getLong(4); String duration = cursor.getString(18); String tzId = null; if (allDay) { e.setDtStart(tsStart, null); // provide only DTEND and not DURATION for all-day events if (tsEnd == 0) { Dur dur = new Dur(duration); java.util.Date dEnd = dur.getTime(new java.util.Date(tsStart)); tsEnd = dEnd.getTime(); } e.setDtEnd(tsEnd, null); } else { // use the start time zone for the end time, too // because apps like Samsung Planner allow the user to change "the" time zone but change // the start time zone only tzId = cursor.getString(5); e.setDtStart(tsStart, tzId); if (tsEnd != 0) e.setDtEnd(tsEnd, tzId); else if (!StringUtils.isEmpty(duration)) e.setDuration(new Duration(new Dur(duration))); } // recurrence try { String strRRule = cursor.getString(10); if (!StringUtils.isEmpty(strRRule)) e.setRrule(new RRule(strRRule)); String strRDate = cursor.getString(11); if (!StringUtils.isEmpty(strRDate)) { RDate rDate = new RDate(); rDate.setValue(strRDate); e.setRdate(rDate); } String strExRule = cursor.getString(12); if (!StringUtils.isEmpty(strExRule)) { ExRule exRule = new ExRule(); exRule.setValue(strExRule); e.setExrule(exRule); } String strExDate = cursor.getString(13); if (!StringUtils.isEmpty(strExDate)) { // ignored, see https://code.google.com/p/android/issues/detail?id=21426 ExDate exDate = new ExDate(); exDate.setValue(strExDate); e.setExdate(exDate); } } catch (ParseException ex) { Log.w(TAG, "Couldn't parse recurrence rules, ignoring", ex); } catch (IllegalArgumentException ex) { Log.w(TAG, "Invalid recurrence rules, ignoring", ex); } // status switch (cursor.getInt(8)) { case Events.STATUS_CONFIRMED: e.setStatus(Status.VEVENT_CONFIRMED); break; case Events.STATUS_TENTATIVE: e.setStatus(Status.VEVENT_TENTATIVE); break; case Events.STATUS_CANCELED: e.setStatus(Status.VEVENT_CANCELLED); } // availability e.setOpaque(cursor.getInt(19) != Events.AVAILABILITY_FREE); // attendees if (cursor.getInt(14) != 0) { // has attendees try { e.setOrganizer(new Organizer(new URI("mailto", cursor.getString(15), null))); } catch (URISyntaxException ex) { Log.e(TAG, "Error when creating ORGANIZER URI, ignoring", ex); } populateAttendees(e); } // classification switch (cursor.getInt(9)) { case Events.ACCESS_CONFIDENTIAL: case Events.ACCESS_PRIVATE: e.setForPublic(false); break; case Events.ACCESS_PUBLIC: e.setForPublic(true); } populateReminders(e); } else throw new RecordNotFoundException(); } catch (RemoteException ex) { throw new LocalStorageException(ex); } }
/** * Fügt die Wiederholungen des übergebenen Appointment-Objekts dem übergebenen * Event-Objekt hinzu. * * @param appointment Ein Rapla Appointment. */ private void addRepeatings(Appointment appointment, PropertyList properties) { Repeating repeating = appointment.getRepeating(); if (repeating == null) { return; } // This returns the strings DAYLY, WEEKLY, MONTHLY, YEARLY String type = repeating.getType().toString().toUpperCase(); Recur recur; // here is evaluated, if a COUNT is set in Rapla, or an enddate is // specified if (repeating.getNumber() == -1) { recur = new Recur(type, -1); } else if (repeating.isFixedNumber()) { recur = new Recur(type, repeating.getNumber()); } else { net.fortuna.ical4j.model.Date endDate = new net.fortuna.ical4j.model.Date(repeating.getEnd()); // TODO do we need to translate the enddate in utc? recur = new Recur(type, endDate); } if (repeating.isDaily()) { // DAYLY -> settings : intervall recur.setInterval(repeating.getInterval()); } else if (repeating.isWeekly()) { // WEEKLY -> settings : every nTh Weekday recur.setInterval(repeating.getInterval()); calendar.setTime(appointment.getStart()); recur.getDayList().add(WeekDay.getWeekDay(calendar)); } else if (repeating.isMonthly()) { // MONTHLY -> settings : every nTh Weekday recur.setInterval(repeating.getInterval()); calendar.setTime(appointment.getStart()); int weekofmonth = Math.round(calendar.get(java.util.Calendar.DAY_OF_MONTH) / DateTools.DAYS_PER_WEEK) + 1; recur.getDayList().add(new WeekDay(WeekDay.getWeekDay(calendar), weekofmonth)); } else if (repeating.isYearly()) { // YEARLY -> settings : every nTh day mTh Monthname calendar.setTime(appointment.getStart()); calendar.get(java.util.Calendar.DAY_OF_YEAR); } else { getLogger().warn("Invalid data in recurrency rule!"); } properties.add(new RRule(recur)); // bugfix - if rapla has no exceptions, an empty EXDATE: element is // produced. This may bother some iCal tools if (repeating.getExceptions().length == 0) { return; } // Add exception dates // DateList dl = new DateList(Value.DATE); ExDate exDate = new ExDate(); TimeZoneRegistry registry = TimeZoneRegistryFactory.getInstance().createRegistry(); net.fortuna.ical4j.model.TimeZone tz = registry.getTimeZone(timeZone.getID()); // rku: use seperate EXDATE for each exception for (Iterator<Date> itExceptions = Arrays.asList(repeating.getExceptions()).iterator(); itExceptions.hasNext(); ) { // DateList dl = new DateList(Value.DATE); Date date = itExceptions.next(); // dl.add(new net.fortuna.ical4j.model.Date( date)); java.util.Calendar cal = raplaLocale.createCalendar(); cal.setTime(date); int year = cal.get(java.util.Calendar.YEAR); int day_of_year = cal.get(java.util.Calendar.DAY_OF_YEAR); cal.setTime(appointment.getStart()); cal.set(java.util.Calendar.YEAR, year); cal.set(java.util.Calendar.DAY_OF_YEAR, day_of_year); int offset = (int) (tz.getOffset(DateTools.cutDate(date).getTime()) / DateTools.MILLISECONDS_PER_HOUR); cal.add(java.util.Calendar.HOUR, -offset); Date dateToSave = cal.getTime(); net.fortuna.ical4j.model.DateTime dateTime = new net.fortuna.ical4j.model.DateTime(); dateTime.setTime(dateToSave.getTime()); exDate.getDates().add(dateTime); } exDate.setTimeZone(tz); properties.add(exDate); // properties.add(new ExDate(dl)); }