|
|
/*
|
|
|
* 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;
|
|
|
|
|
|
/**
|
|
|
* <p>Synchronization manager for CardDAV collections; handles contacts and groups.</p>
|
|
|
*/
|
|
|
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;
|
|
|
}
|
|
|
}
|