/* * Copyright © 2013 – 2015 Ricki Hirner (bitfire web engineering). * All rights reserved. This program and the accompanying materials * are made available under the terms of the GNU Public License v3.0 * which accompanies this distribution, and is available at * http://www.gnu.org/licenses/gpl.html */ package at.bitfire.davdroid.syncadapter; import android.accounts.Account; import android.content.Context; import android.content.SyncResult; import android.os.Bundle; import org.apache.commons.codec.Charsets; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import at.bitfire.davdroid.AccountSettings; import at.bitfire.davdroid.App; import at.bitfire.davdroid.Constants; import at.bitfire.davdroid.InvalidAccountException; import at.bitfire.davdroid.R; import at.bitfire.davdroid.journalmanager.Exceptions; import at.bitfire.davdroid.journalmanager.JournalEntryManager; import at.bitfire.davdroid.resource.LocalCalendar; import at.bitfire.davdroid.resource.LocalEvent; import at.bitfire.davdroid.resource.LocalResource; import at.bitfire.ical4android.CalendarStorageException; import at.bitfire.ical4android.Event; import at.bitfire.ical4android.InvalidCalendarException; import at.bitfire.vcard4android.ContactsStorageException; import okhttp3.HttpUrl; /** *

Synchronization manager for CardDAV collections; handles contacts and groups.

*/ public class CalendarSyncManager extends SyncManager { protected static final int MAX_MULTIGET = 10; final private HttpUrl remote; public CalendarSyncManager(Context context, Account account, AccountSettings settings, Bundle extras, String authority, SyncResult result, LocalCalendar calendar, HttpUrl remote) throws InvalidAccountException { super(context, account, settings, extras, authority, result, "calendar/" + calendar.getId()); localCollection = calendar; this.remote = remote; } @Override protected int notificationId() { return Constants.NOTIFICATION_CALENDAR_SYNC; } @Override protected String getSyncErrorTitle() { return context.getString(R.string.sync_error_calendar, account.name); } @Override protected void prepare() throws ContactsStorageException { journal = new JournalEntryManager(httpClient, remote, localCalendar().getName()); } @Override protected void applyLocalEntries() throws IOException, Exceptions.HttpException, ContactsStorageException, CalendarStorageException { } @Override protected void prepareDirty() throws CalendarStorageException, ContactsStorageException { super.prepareDirty(); localCalendar().processDirtyExceptions(); } // helpers private LocalCalendar localCalendar() { return (LocalCalendar) localCollection; } protected void processSyncEntry(SyncEntry cEntry) throws IOException, ContactsStorageException, CalendarStorageException, InvalidCalendarException { InputStream is = new ByteArrayInputStream(cEntry.getContent().getBytes(Charsets.UTF_8)); Event[] events = Event.fromStream(is, Charsets.UTF_8); if (events.length == 0) { App.log.warning("Received VCard without data, ignoring"); return; } else if (events.length > 1) App.log.warning("Received multiple VCALs, using first one"); Event event = events[0]; if (cEntry.isAction(SyncEntry.Actions.ADD) || cEntry.isAction(SyncEntry.Actions.CHANGE)) { LocalResource local = processEvent(event); if (local != null) { localResources.put(local.getUuid(), local); } } else { LocalResource local = localResources.get(event.uid); App.log.info("Removing local record #" + local.getId() + " which has been deleted on the server"); localResources.remove(local.getUuid()); local.delete(); } } private LocalResource processEvent(final Event newData) throws IOException, ContactsStorageException, CalendarStorageException { // delete local event, if it exists LocalEvent localEvent = (LocalEvent) localResources.get(newData.uid); if (localEvent != null) { App.log.info("Updating " + newData.uid + " in local calendar"); localEvent.setETag(newData.uid); localEvent.update(newData); syncResult.stats.numUpdates++; } else { App.log.info("Adding " + newData.uid + " to local calendar"); localEvent = new LocalEvent(localCalendar(), newData, newData.uid, null); localEvent.add(); syncResult.stats.numInserts++; } return localEvent; } }