src/org/gege/caldavsyncadapter/syncadapter/SyncAdapter.java

Tue, 10 Feb 2015 22:40:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 10 Feb 2015 22:40:00 +0100
changeset 8
ec8af0e3fbc2
parent 0
fb9019fb1bf7
permissions
-rw-r--r--

Merge https://github.com/gggard/AndroidCaldavSyncAdapater/pull/206/

     1 /**
     2  * Copyright (c) 2012-2013, Gerald Garcia, David Wiesner, Timo Berger
     3  *
     4  * This file is part of Andoid Caldav Sync Adapter Free.
     5  *
     6  * Andoid Caldav Sync Adapter Free is free software: you can redistribute 
     7  * it and/or modify it under the terms of the GNU General Public License 
     8  * as published by the Free Software Foundation, either version 3 of the 
     9  * License, or at your option any later version.
    10  *
    11  * Andoid Caldav Sync Adapter Free is distributed in the hope that 
    12  * it will be useful, but WITHOUT ANY WARRANTY; without even the implied 
    13  * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    14  * GNU General Public License for more details.
    15  *
    16  * You should have received a copy of the GNU General Public License
    17  * along with Andoid Caldav Sync Adapter Free.  
    18  * If not, see <http://www.gnu.org/licenses/>.
    19  *
    20  */
    22 package org.gege.caldavsyncadapter.syncadapter;
    24 import android.accounts.Account;
    25 import android.accounts.AccountManager;
    26 import android.content.AbstractThreadedSyncAdapter;
    27 import android.content.ContentProviderClient;
    28 import android.content.ContentUris;
    29 import android.content.ContentValues;
    30 import android.content.Context;
    31 import android.content.SyncResult;
    32 import android.content.SyncStats;
    33 import android.content.pm.PackageManager.NameNotFoundException;
    34 import android.database.Cursor;
    35 import android.net.Uri;
    36 import android.os.Bundle;
    37 import android.os.RemoteException;
    38 import android.provider.CalendarContract.Attendees;
    39 import android.provider.CalendarContract.Calendars;
    40 import android.provider.CalendarContract.Events;
    41 import android.provider.CalendarContract.Reminders;
    42 import android.util.Log;
    44 import net.fortuna.ical4j.data.ParserException;
    46 import org.apache.http.ParseException;
    47 import org.apache.http.client.ClientProtocolException;
    48 import org.gege.caldavsyncadapter.Constants;
    49 import org.gege.caldavsyncadapter.Event;
    50 import org.gege.caldavsyncadapter.android.entities.AndroidEvent;
    51 import org.gege.caldavsyncadapter.authenticator.AuthenticatorActivity;
    52 import org.gege.caldavsyncadapter.caldav.CaldavFacade;
    53 import org.gege.caldavsyncadapter.caldav.CaldavProtocolException;
    54 import org.gege.caldavsyncadapter.caldav.entities.CalendarEvent;
    55 import org.gege.caldavsyncadapter.caldav.entities.CalendarList;
    56 import org.gege.caldavsyncadapter.caldav.entities.DavCalendar;
    57 import org.gege.caldavsyncadapter.caldav.entities.DavCalendar.CalendarSource;
    58 import org.gege.caldavsyncadapter.syncadapter.notifications.NotificationsHelper;
    59 import org.xml.sax.SAXException;
    61 import java.io.IOException;
    62 import java.net.URI;
    63 import java.net.URISyntaxException;
    64 import java.util.ArrayList;
    66 import javax.xml.parsers.ParserConfigurationException;
    68 //import java.net.MalformedURLException;
    69 //import java.security.GeneralSecurityException;
    71 public class SyncAdapter extends AbstractThreadedSyncAdapter {
    73     private static final String TAG = "SyncAdapter";
    74     private AccountManager mAccountManager;
    75     private String mVersion = "";
    76     private int mCountPerformSync = 0;
    77     private int mCountSyncCanceled = 0;
    78     private int mCountProviderFailed = 0;
    80     private int mCountProviderFailedMax = 3;
    81 //	private Context mContext;
    84 /*	private static final String[] CALENDAR_PROJECTION = new String[] {
    85 	    Calendars._ID,                           // 0
    86 	    Calendars.ACCOUNT_NAME,                  // 1
    87 	    Calendars.CALENDAR_DISPLAY_NAME,         // 2
    88 	    Calendars.OWNER_ACCOUNT,                 // 3
    89 	    Calendar.CTAG                            // 4
    90 	};*/
    92 /*	// The indices for the projection array above.
    93 	private static final int PROJECTION_ID_INDEX = 0;
    94 	private static final int PROJECTION_ACCOUNT_NAME_INDEX = 1;
    95 	private static final int PROJECTION_DISPLAY_NAME_INDEX = 2;
    96 	private static final int PROJECTION_OWNER_ACCOUNT_INDEX = 3;
    97 */
    99 /*
   100 	private static final String[] EVENT_PROJECTION = new String[] {
   101 		Events._ID,
   102 		Events._SYNC_ID,
   103 		Events.SYNC_DATA1,
   104 		Events.CALENDAR_ID
   105 	};
   106 */
   108     // ignore same CTag
   109     //private static final boolean FORCE_SYNCHRONIZE = false;
   110     // drop all calendar before synchro
   111     //private static final boolean DROP_CALENDAR_EVENTS = false;
   113     public SyncAdapter(Context context, boolean autoInitialize) {
   114         super(context, autoInitialize);
   115         //android.os.Debug.waitForDebugger();
   116         mAccountManager = AccountManager.get(context);
   117         try {
   118             mVersion = context.getPackageManager()
   119                     .getPackageInfo(context.getPackageName(), 0).versionName;
   120         } catch (NameNotFoundException e) {
   121             e.printStackTrace();
   122         }
   123 //		mContext = context;
   124     }
   126     @Override
   127     public void onPerformSync(Account account, Bundle extras, String authority,
   128                               ContentProviderClient provider, SyncResult syncResult) {
   129         boolean bolError = false;
   131         String url = mAccountManager.getUserData(account, AuthenticatorActivity.USER_DATA_URL_KEY);
   132         String trust = mAccountManager.getUserData(account, Constants.USER_DATA_TRUST_ALL_KEY);
   133         this.mCountPerformSync += 1;
   134         Log.v(TAG, "onPerformSync() count:" + String.valueOf(this.mCountPerformSync) + " on " + account.name + " with URL " + url);
   136         CalendarList serverCalList;
   138         CalendarList androidCalList = new CalendarList(account, provider, CalendarSource.Android, url);
   139         androidCalList.readCalendarFromClient();
   140         ArrayList<Uri> notifyList = new ArrayList<Uri>();
   142         try {
   143             String Username = "";
   144             String UserDataVersion = mAccountManager.getUserData(account, AuthenticatorActivity.USER_DATA_VERSION);
   145             if (UserDataVersion == null) {
   146                 Username = account.name;
   147             } else {
   148                 Username = mAccountManager.getUserData(account, AuthenticatorActivity.USER_DATA_USERNAME);
   149             }
   151             CaldavFacade facade = new CaldavFacade(Username, mAccountManager.getPassword(account), url, trust);
   152             facade.setAccount(account);
   153             facade.setProvider(provider);
   154             facade.setVersion(mVersion);
   155             serverCalList = facade.getCalendarList(this.getContext());
   156             //String davProperties = facade.getLastDav();
   157             Log.i(TAG, String.valueOf(androidCalList.getCalendarList()
   158                     .size()) + " calendars found at android");
   160             for (DavCalendar serverCalendar : serverCalList.getCalendarList()) {
   161                 Log.i(TAG, "Detected calendar name=" + serverCalendar.getCalendarDisplayName() + " URI=" + serverCalendar
   162                         .getURI());
   164                 Uri androidCalendarUri = serverCalendar.checkAndroidCalendarList(androidCalList, this
   165                         .getContext());
   167                 // check if the adapter was able to get an existing calendar or create a new one
   168                 if (androidCalendarUri != null) {
   169                     // the provider seems to work correct, reset the counter
   170                     mCountProviderFailed = 0;
   171                     DavCalendar androidCalendar = androidCalList.getCalendarByAndroidUri(androidCalendarUri);
   173                     //if ((FORCE_SYNCHRONIZE) || (androidCalendar.getcTag() == null) || (!androidCalendar.getcTag().equals(serverCalendar.getcTag()))) {
   174                     if ((androidCalendar.getcTag() == null) || (!androidCalendar.getcTag()
   175                             .equals(serverCalendar.getcTag()))) {
   176                         Log.d(TAG, "CTag has changed, something to synchronise");
   177                         if (serverCalendar.readCalendarEvents(facade)) {
   178                             this.synchroniseEvents(androidCalendar, serverCalendar, syncResult.stats, notifyList);
   180                             Log.d(TAG, "Updating stored CTag");
   181                             //serverCalendar.updateAndroidCalendar(androidCalendarUri, Calendar.CTAG, serverCalendar.getcTag());
   182                             androidCalendar.setCTag(serverCalendar.getcTag(), true);
   183                         } else {
   184                             Log.d(TAG, "unable to read events from server calendar");
   185                         }
   186                     } else {
   187                         Log.d(TAG, "CTag has not changed, nothing to do");
   189 						/* this is unnecessary. "SkippedEntries" are:
   190 						 * Counter for tracking how many entries, either from the server or the local store, 
   191 						 * were ignored during the sync operation. This could happen if the SyncAdapter detected 
   192 						 * some unparsable data but decided to skip it and move on rather than failing immediately. 
   193 						 */
   195 						/*long CalendarID = ContentUris.parseId(androidCalendarUri);
   196 						String selection = "(" + Events.CALENDAR_ID + " = ?)";
   197 						String[] selectionArgs = new String[] {String.valueOf(CalendarID)}; 
   198 						Cursor countCursor = provider.query(Events.CONTENT_URI, new String[] {"count(*) AS count"},
   199 					                selection,
   200 					                selectionArgs,
   201 					                null);
   203 				        countCursor.moveToFirst();
   204 				        int count = countCursor.getInt(0);
   205 				        syncResult.stats.numSkippedEntries += count;
   206 				        countCursor.close();*/
   208                     }
   210                     this.checkDirtyAndroidEvents(provider, account, androidCalendarUri, facade, serverCalendar
   211                             .getURI(), syncResult.stats, notifyList);
   212                 } else {
   213                     // this happens if the data provider failes to get an existing or create a new calendar
   214                     mCountProviderFailed += 1;
   215                     Log.e(TAG, "failed to get an existing or create a new calendar");
   216                     syncResult.stats.numIoExceptions += 1;
   217                     if (mCountProviderFailed >= mCountProviderFailedMax) {
   218                         // see issue #96
   219                         NotificationsHelper.signalSyncErrors(this.getContext(), "Caldav sync error (provider failed)", "are you using CyanogenMod in Incognito Mode?");
   220                     } else {
   221                         NotificationsHelper.signalSyncErrors(this.getContext(), "Caldav sync error (provider failed)", "the provider failed to get an existing or create a new calendar");
   222                     }
   223                     bolError = true;
   224                 }
   225             }
   227             if (!bolError) {
   228                 // check whether a calendar is not synced -> delete it at android
   229                 androidCalList.deleteCalendarOnClientSideOnly(this.getContext());
   230             }
   232             // notify the ContentResolver
   233             for (Uri uri : androidCalList.getNotifyList()) {
   234                 this.getContext().getContentResolver().notifyChange(uri, null);
   235             }
   236             for (Uri uri : serverCalList.getNotifyList()) {
   237                 this.getContext().getContentResolver().notifyChange(uri, null);
   238             }
   239             for (Uri uri : notifyList) {
   240                 this.getContext().getContentResolver().notifyChange(uri, null);
   241             }
   243             //Log.i(TAG,"Statistiks for Calendar: " + serverCalendar.getURI().toString());
   244             //Log.i(TAG,"Statistiks for AndroidCalendar: " + androidCalendar.getAndroidCalendarUri().toString());
   245             Log.i(TAG, "Entries:                       " + String.valueOf(syncResult.stats.numEntries));
   246             Log.i(TAG, "Rows inserted:                 " + String.valueOf(syncResult.stats.numInserts));
   247             Log.i(TAG, "Rows updated:                  " + String.valueOf(syncResult.stats.numUpdates));
   248             Log.i(TAG, "Rows deleted:                  " + String.valueOf(syncResult.stats.numDeletes));
   249             Log.i(TAG, "Rows skipped:                  " + String.valueOf(syncResult.stats.numSkippedEntries));
   250             Log.i(TAG, "Io Exceptions:                 " + String.valueOf(syncResult.stats.numIoExceptions));
   251             Log.i(TAG, "Parse Exceptions:              " + String.valueOf(syncResult.stats.numParseExceptions));
   252             Log.i(TAG, "Auth Exceptions:               " + String.valueOf(syncResult.stats.numAuthExceptions));
   253             Log.i(TAG, "Conflict Detected Exceptions:  " + String.valueOf(syncResult.stats.numConflictDetectedExceptions));
   255 		/*} catch (final AuthenticatorException e) {
   256             syncResult.stats.numParseExceptions++;
   257             Log.e(TAG, "AuthenticatorException", e);*/
   258         /*} catch (final OperationCanceledException e) {
   259             Log.e(TAG, "OperationCanceledExcetpion", e);*/
   260         } catch (final IOException e) {
   261             Log.e(TAG, "IOException", e);
   262             syncResult.stats.numIoExceptions++;
   263             NotificationsHelper.signalSyncErrors(this.getContext(), "Caldav sync error (IO)", e.getMessage());
   264             //NotificationsHelper.getCurrentSyncLog().addException(e);
   265             /*} catch (final AuthenticationException e) {
   266             //mAccountManager.invalidateAuthToken(Constants.ACCOUNT_TYPE, authtoken);
   267             syncResult.stats.numAuthExceptions++;
   268             Log.e(TAG, "AuthenticationException", e);*/
   269         } catch (final ParseException e) {
   270             syncResult.stats.numParseExceptions++;
   271             Log.e(TAG, "ParseException", e);
   272             NotificationsHelper.signalSyncErrors(this.getContext(), "Caldav sync error (parsing)", e
   273                     .getMessage());
   274             //NotificationsHelper.getCurrentSyncLog().addException(e);
   275         /*} catch (final JSONException e) {
   276             syncResult.stats.numParseExceptions++;
   277             Log.e(TAG, "JSONException", e);*/
   278         } catch (Exception e) {
   279             Log.e(TAG, "Updating calendar exception " + e.getClass().getName(), e);
   280             syncResult.stats.numParseExceptions++;
   281             NotificationsHelper.signalSyncErrors(this.getContext(), "Caldav sync error (general)", e
   282                     .getMessage());
   283             //NotificationsHelper.getCurrentSyncLog().addException(e);
   284             //throw new RuntimeException(e);
   285         }
   286     }
   288     public void onSyncCanceled() {
   289         //TODO: implement SyncCanceled
   290         this.mCountSyncCanceled += 1;
   291         Log.v(TAG, "onSyncCanceled() count:" + String.valueOf(this.mCountSyncCanceled));
   292     }
   295     /**
   296      * both calender event and android event have been found.
   297      * server wins always at the moment.
   298      *
   299      * @param androidCalendar
   300      * @param serverCalendar
   301      * @param stats
   302      * @param notifyList
   303      * @throws ClientProtocolException
   304      * @throws URISyntaxException
   305      * @throws IOException
   306      * @throws ParserConfigurationException
   307      * @throws SAXException
   308      * @throws RemoteException
   309      * @throws CaldavProtocolException
   310      * @throws ParserException
   311      * @see SyncAdapter#updateAndroidEvent(ContentProviderClient, Account, AndroidEvent, CalendarEvent)
   312      * @see SyncAdapter#tagAndroidEvent(ContentProviderClient, Account, AndroidEvent)
   313      * @see SyncAdapter#untagAndroidEvents(ContentProviderClient, Account, Uri)
   314      * @see SyncAdapter#deleteUntaggedEvents(ContentProviderClient, Account, Uri)
   315      */
   316     private void synchroniseEvents(
   317             DavCalendar androidCalendar,
   318             DavCalendar serverCalendar,
   319             SyncStats stats,
   320             ArrayList<Uri> notifyList
   321     ) throws ClientProtocolException, URISyntaxException, IOException, ParserConfigurationException, SAXException, RemoteException, CaldavProtocolException, ParserException {
   323 		/*if (DROP_CALENDAR_EVENTS) {
   324 			dropAllEvents(account, provider, androidCalendar.getAndroidCalendarUri());
   325 		}*/
   327         int rowInsert = 0;
   328         int rowUpdate = 0;
   329         int rowTag = 0;
   330         int rowDelete = 0;
   331         int rowUntag = 0;
   332         int rowSkip = 0;
   334         for (CalendarEvent calendarEvent : serverCalendar.getCalendarEvents()) {
   335             try {
   336                 AndroidEvent androidEvent = calendarEvent.getAndroidEvent(androidCalendar);
   338                 Log.i(TAG, "Event " + calendarEvent.getUri()
   339                         .toString() + " androidUri=" + androidEvent);
   341                 if (androidEvent == null) {
   342 					/* new android event */
   343                     if (calendarEvent.createAndroidEvent(androidCalendar)) {
   344                         rowInsert += 1;
   345                         androidEvent = calendarEvent.getAndroidEvent(androidCalendar);
   346                         notifyList.add(androidEvent.getUri());
   347                     } else {
   348                         rowSkip += 1;
   349                     }
   350                 } else {
   351 					/* the android exists */
   352                     String androidETag = androidEvent.getETag();
   353                     if (androidETag == null)
   354                         androidETag = "";
   355                     Log.d(TAG, "Event compare: " + androidETag + " <> " + calendarEvent.getETag()
   356                             .toString());
   357                     if ((androidEvent.getETag() == null) || (!androidETag.equals(calendarEvent.getETag()))) {
   358 						/* the android event is getting updated */
   359                         if (calendarEvent.updateAndroidEvent(androidEvent)) {
   360                             rowUpdate += 1;
   361                             notifyList.add(androidEvent.getUri());
   362                         } else {
   363                             rowSkip += 1;
   364                         }
   365                     }
   366                 }
   367                 if (androidEvent != null)
   368                     //if (androidEvent.tagAndroidEvent())
   369                     if (androidCalendar.tagAndroidEvent(androidEvent))
   370                         rowTag += 1;
   373             } catch (ParserException ex) {
   374                 Log.e(TAG, "Parser exception", ex);
   375                 stats.numParseExceptions++;
   377                 NotificationsHelper.signalSyncErrors(getContext(), "Caldav sync error (parsing)", ex
   378                         .getMessage());
   379                 //NotificationsHelper.getCurrentSyncLog().addException(ex);
   380             } catch (CaldavProtocolException ex) {
   381                 Log.e(TAG, "Caldav exception", ex);
   382                 stats.numParseExceptions++;
   384                 NotificationsHelper.signalSyncErrors(getContext(), "Caldav sync error (caldav)", ex.getMessage());
   385                 //NotificationsHelper.getCurrentSyncLog().addException(ex);
   386             }
   387         }
   389         rowDelete = androidCalendar.deleteUntaggedEvents();
   390         rowUntag = androidCalendar.untagAndroidEvents();
   392 		/*Log.i(TAG,"Statistiks for Calendar: " + serverCalendar.getURI().toString());
   393 		Log.i(TAG,"Statistiks for AndroidCalendar: " + androidCalendar.getAndroidCalendarUri().toString());
   394 		Log.i(TAG,"Rows inserted: " + String.valueOf(rowInsert));
   395 		Log.i(TAG,"Rows updated:  " + String.valueOf(rowUpdate));
   396 		Log.i(TAG,"Rows deleted:  " + String.valueOf(rowDelete));
   397 		Log.i(TAG,"Rows skipped:  " + String.valueOf(rowSkip));*/
   398         Log.i(TAG, "Rows tagged:   " + String.valueOf(rowTag));
   399         Log.i(TAG, "Rows untagged: " + String.valueOf(rowUntag));
   401         stats.numInserts += rowInsert;
   402         stats.numUpdates += rowUpdate;
   403         stats.numDeletes += rowDelete;
   404         stats.numSkippedEntries += rowSkip;
   405         stats.numEntries += rowInsert + rowUpdate + rowDelete;
   407     }
   409     /**
   410      * checks the android events for the dirty flag.
   411      * the flag is set by android when the event has been changed.
   412      * the dirty flag is removed when an android event has been updated from calendar event
   413      *
   414      * @param provider
   415      * @param account
   416      * @param calendarUri
   417      * @param facade
   418      * @param caldavCalendarUri
   419      * @param stats
   420      * @param notifyList
   421      * @return count of dirty events
   422      */
   423     private int checkDirtyAndroidEvents(
   424             ContentProviderClient provider,
   425             Account account,
   426             Uri calendarUri,
   427             CaldavFacade facade,
   428             URI caldavCalendarUri,
   429             SyncStats stats,
   430             ArrayList<Uri> notifyList
   431     ) {
   432         Cursor curEvent = null;
   433         Cursor curAttendee = null;
   434         Cursor curReminder = null;
   435         Long EventID;
   436         Long CalendarID;
   437         AndroidEvent androidEvent = null;
   438         int rowDirty = 0;
   439         int rowInsert = 0;
   440         int rowUpdate = 0;
   441         int rowDelete = 0;
   443         try {
   444             CalendarID = ContentUris.parseId(calendarUri);
   445             String selection = "(" + Events.DIRTY + " = ?) AND (" + Events.CALENDAR_ID + " = ?)";
   446             String[] selectionArgs = new String[]{"1", CalendarID.toString()};
   447             curEvent = provider.query(Events.CONTENT_URI, null, selection, selectionArgs, null);
   449             while (curEvent.moveToNext()) {
   450                 EventID = curEvent.getLong(curEvent.getColumnIndex(Events._ID));
   451                 Uri returnedUri = ContentUris.withAppendedId(Events.CONTENT_URI, EventID);
   453                 //androidEvent = new AndroidEvent(account, provider, returnedUri, calendarUri);
   454                 androidEvent = new AndroidEvent(returnedUri, calendarUri);
   455                 androidEvent.readContentValues(curEvent);
   457                 selection = "(" + Attendees.EVENT_ID + " = ?)";
   458                 selectionArgs = new String[]{String.valueOf(EventID)};
   459                 curAttendee = provider.query(Attendees.CONTENT_URI, null, selection, selectionArgs, null);
   460                 selection = "(" + Reminders.EVENT_ID + " = ?)";
   461                 selectionArgs = new String[]{String.valueOf(EventID)};
   462                 curReminder = provider.query(Reminders.CONTENT_URI, null, selection, selectionArgs, null);
   463                 androidEvent.readAttendees(curAttendee);
   464                 androidEvent.readReminder(curReminder);
   465                 curAttendee.close();
   466                 curReminder.close();
   468                 String SyncID = androidEvent.ContentValues.getAsString(Events._SYNC_ID);
   470                 boolean Deleted = false;
   471                 int intDeleted = 0;
   472                 intDeleted = curEvent.getInt(curEvent.getColumnIndex(Events.DELETED));
   473                 Deleted = (intDeleted == 1);
   475                 if (SyncID == null) {
   476                     // new Android event
   477                     String newGUID = java.util.UUID.randomUUID().toString() + "-caldavsyncadapter";
   478                     String calendarPath = caldavCalendarUri.getPath();
   479                     if (!calendarPath.endsWith("/"))
   480                         calendarPath += "/";
   482                     SyncID = calendarPath + newGUID + ".ics";
   484                     androidEvent.createIcs(newGUID);
   486                     if (facade.createEvent(URI.create(SyncID), androidEvent.getIcsEvent()
   487                             .toString())) {
   488                         //HINT: bugfix for google calendar replace("@", "%40")
   489                         if (SyncID.contains("@"))
   490                             SyncID = SyncID.replace("@", "%40");
   491                         ContentValues values = new ContentValues();
   492                         values.put(Events._SYNC_ID, SyncID);
   494                         //google doesn't send the etag after creation
   495                         //HINT: my SabreDAV send always the same etag after putting a new event
   496                         //String LastETag = facade.getLastETag();
   497                         //if (!LastETag.equals("")) {
   498                         //	values.put(Event.ETAG, LastETag);
   499                         //} else {
   500                         //so get the etag with a new REPORT
   501                         CalendarEvent calendarEvent = new CalendarEvent(account, provider);
   502                         calendarEvent.calendarURL = caldavCalendarUri.toURL();
   503                         URI SyncURI = new URI(SyncID);
   504                         calendarEvent.setUri(SyncURI);
   505                         CaldavFacade.getEvent(calendarEvent);
   506                         values.put(Event.ETAG, calendarEvent.getETag());
   507                         //}
   508                         values.put(Event.UID, newGUID);
   509                         values.put(Events.DIRTY, 0);
   510                         values.put(Event.RAWDATA, androidEvent.getIcsEvent().toString());
   512                         int rowCount = provider.update(asSyncAdapter(androidEvent.getUri(), account.name, account.type), values, null, null);
   513                         if (rowCount == 1) {
   514                             rowInsert += 1;
   515                             notifyList.add(androidEvent.getUri());
   516                         }
   517                     }
   518                 } else if (Deleted) {
   519                     // deleted Android event
   520                     if (facade.deleteEvent(URI.create(SyncID), androidEvent.getETag())) {
   521                         String mSelectionClause = "(" + Events._ID + "= ?)";
   522                         String[] mSelectionArgs = {String.valueOf(EventID)};
   524                         int countDeleted = provider.delete(asSyncAdapter(Events.CONTENT_URI, account.name, account.type), mSelectionClause, mSelectionArgs);
   526                         if (countDeleted == 1) {
   527                             rowDelete += 1;
   528                             notifyList.add(androidEvent.getUri());
   529                         }
   530                     }
   531                 } else {
   532                     //update the android event to the server
   533                     String uid = androidEvent.getUID();
   534                     if ((uid == null) || (uid.equals(""))) {
   535                         //COMPAT: this is needed because in the past, the UID was not stored in the android event
   536                         CalendarEvent calendarEvent = new CalendarEvent(account, provider);
   537                         URI syncURI = new URI(SyncID);
   538                         calendarEvent.setUri(syncURI);
   539                         calendarEvent.calendarURL = caldavCalendarUri.toURL();
   540                         if (calendarEvent.fetchBody()) {
   541                             calendarEvent.readContentValues();
   542                             uid = calendarEvent.getUID();
   543                         }
   544                     }
   545                     if (uid != null) {
   546                         androidEvent.createIcs(uid);
   548                         if (facade.updateEvent(URI.create(SyncID), androidEvent.getIcsEvent()
   549                                 .toString(), androidEvent.getETag())) {
   550                             selection = "(" + Events._ID + "= ?)";
   551                             selectionArgs = new String[]{EventID.toString()};
   552                             androidEvent.ContentValues.put(Events.DIRTY, 0);
   554                             //google doesn't send the etag after update
   555                             String LastETag = facade.getLastETag();
   556                             if (!LastETag.equals("")) {
   557                                 androidEvent.ContentValues.put(Event.ETAG, LastETag);
   558                             } else {
   559                                 //so get the etag with a new REPORT
   560                                 CalendarEvent calendarEvent = new CalendarEvent(account, provider);
   561                                 calendarEvent.calendarURL = caldavCalendarUri.toURL();
   562                                 URI SyncURI = new URI(SyncID);
   563                                 calendarEvent.setUri(SyncURI);
   564                                 CaldavFacade.getEvent(calendarEvent);
   565                                 androidEvent.ContentValues.put(Event.ETAG, calendarEvent.getETag());
   566                             }
   567                             androidEvent.ContentValues.put(Event.RAWDATA, androidEvent.getIcsEvent()
   568                                     .toString());
   569                             int RowCount = provider.update(asSyncAdapter(androidEvent.getUri(), account.name, account.type), androidEvent.ContentValues, null, null);
   571                             if (RowCount == 1) {
   572                                 rowUpdate += 1;
   573                                 notifyList.add(androidEvent.getUri());
   574                             }
   575                         } else {
   576                             rowDirty += 1;
   577                         }
   578                     } else {
   579                         rowDirty += 1;
   580                     }
   581                 }
   582             }
   583             curEvent.close();
   585 			/*if ((rowInsert > 0) || (rowUpdate > 0) || (rowDelete > 0) || (rowDirty > 0)) {
   586 				Log.i(TAG,"Android Rows inserted: " + String.valueOf(rowInsert));
   587 				Log.i(TAG,"Android Rows updated:  " + String.valueOf(rowUpdate));
   588 				Log.i(TAG,"Android Rows deleted:  " + String.valueOf(rowDelete));
   589 				Log.i(TAG,"Android Rows dirty:    " + String.valueOf(rowDirty));
   590 			}*/
   592             stats.numInserts += rowInsert;
   593             stats.numUpdates += rowUpdate;
   594             stats.numDeletes += rowDelete;
   595             stats.numSkippedEntries += rowDirty;
   596             stats.numEntries += rowInsert + rowUpdate + rowDelete;
   597         } catch (RemoteException e) {
   598             e.printStackTrace();
   599         } catch (URISyntaxException e) {
   600             // TODO Automatisch generierter Erfassungsblock
   601             e.printStackTrace();
   602         } catch (ClientProtocolException e) {
   603             // TODO Automatisch generierter Erfassungsblock
   604             e.printStackTrace();
   605         } catch (IOException e) {
   606             // TODO Automatisch generierter Erfassungsblock
   607             e.printStackTrace();
   608         } catch (CaldavProtocolException e) {
   609             // TODO Automatisch generierter Erfassungsblock
   610             e.printStackTrace();
   611         } catch (ParserException e) {
   612             // TODO Automatisch generierter Erfassungsblock
   613             e.printStackTrace();
   614         }
   616         return rowDirty;
   617     }
   619 /*	private Account UpgradeAccount(Account OldAccount) {
   620 		String Username = OldAccount.name;
   621 		String Type = OldAccount.type;
   622 		String Password = this.mAccountManager.getPassword(OldAccount);
   623 		String Url = this.mAccountManager.getUserData(OldAccount, AuthenticatorActivity.USER_DATA_URL_KEY);
   625 		Account NewAccount = new Account(Username + AuthenticatorActivity.ACCOUNT_NAME_SPLITTER + Url, Type);
   626 		if (this.mAccountManager.addAccountExplicitly(NewAccount, Password, null)) {
   627 			this.mAccountManager.setUserData(NewAccount, AuthenticatorActivity.USER_DATA_URL_KEY, Url);
   628 			this.mAccountManager.setUserData(NewAccount, AuthenticatorActivity.USER_DATA_USERNAME, Username);
   629 		}
   630 		this.mAccountManager.removeAccount(OldAccount, null, null);
   632 		return NewAccount;
   633 	}*/
   635 /*	private void dropAllEvents(Account account, ContentProviderClient provider,	Uri calendarUri) throws RemoteException {
   637 		Log.i(TAG, "Deleting all calendar events for "+calendarUri);
   639 		String selection = "(" + Events.CALENDAR_ID + " = ?)";
   640 		String[] selectionArgs = new String[] {Long.toString(ContentUris.parseId(calendarUri))}; 
   642 		provider.delete(asSyncAdapter(Events.CONTENT_URI, account.name, account.type), 
   643 				        selection, selectionArgs);
   645 	}*/
   647     private static Uri asSyncAdapter(Uri uri, String account, String accountType) {
   648         return uri.buildUpon()
   649                 .appendQueryParameter(android.provider.CalendarContract.CALLER_IS_SYNCADAPTER, "true")
   650                 .appendQueryParameter(Calendars.ACCOUNT_NAME, account)
   651                 .appendQueryParameter(Calendars.ACCOUNT_TYPE, accountType).build();
   652     }
   654 }

mercurial