kitchensync

standardsync.cpp

00001 /*
00002     This file is part of KitchenSync.
00003 
00004     Copyright (c) 2002 Cornelius Schumacher <schumacher@kde.org>
00005     Copyright (c) 2002,2004 Holger Hans Peter Freyther <freyther@kde.org>
00006 
00007 
00008     This library is free software; you can redistribute it and/or
00009     modify it under the terms of the GNU Library General Public
00010     License as published by the Free Software Foundation; either
00011     version 2 of the License, or (at your option) any later version.
00012 
00013     This library is distributed in the hope that it will be useful,
00014     but WITHOUT ANY WARRANTY; without even the implied warranty of
00015     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00016     Library General Public License for more details.
00017 
00018     You should have received a copy of the GNU Library General Public License
00019     along with this library; see the file COPYING.LIB.  If not, write to
00020     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00021     Boston, MA 02110-1301, USA.
00022 */
00023 
00024 #include "standardsync.h"
00025 
00026 #include "syncer.h"
00027 #include "syncee.h"
00028 
00029 #include <kdebug.h>
00030 
00031 using namespace KSync;
00032 
00033 
00034 /*
00035  * We only do Syncing based on the Record History. First
00036  * Sync should carry the 'Added' Attribute
00037  */
00038 void StandardSync::syncToTarget( Syncee* syncee,
00039                                  Syncee* target,
00040                                  bool override)
00041 {
00042         return syncMeta( syncee, target, override );
00043 }
00044 
00045 
00046 
00047 /*
00048  * We're now in the MetaMode
00049  * First sync added.
00050  * Then check the modified
00051  * Case 1)
00052  *  Modified   ---- untouched ----> Modify
00053  *  Modified   ---- Modified ---> Deconflict
00054  *  Modified   ---- Removed ----> Deconflict
00055  *  and vice versa
00056  *
00057  */
00058 void StandardSync::syncMeta( Syncee* syncee,
00059                            Syncee* target,
00060                            bool over )
00061 {
00062     kdDebug(5250) << "SYNC: SyncMeta " << endl;
00063     QPtrList<SyncEntry> entries = syncee->added();
00064     SyncEntry* entry;
00065     SyncEntry* targetEntry;
00066 
00067 
00068     for ( entry = entries.first(); entry; entry = entries.next() ) {
00069     targetEntry = target->findEntry( entry->id() );
00070     kdDebug(5250) << "SYNC: About to add " << entry->name() << endl;
00071     if(!targetEntry ){
00072       kdDebug(5250) << "SYNC: Not added before " << endl;
00073           addEntry( syncee, target, entry );
00074     }else {
00075       kdDebug(5250) << "SYNC: Added before " << endl;
00076     }
00077     }
00078     /* modified */
00079     syncSyncEntryListToSyncee( syncee->modified(), syncee, target, over );
00080     syncSyncEntryListToSyncee( syncee->removed(), syncee,  target,over );
00081 
00082 }
00083 
00084 /*
00085  * On non trusted Ids let us replace and reset them
00086  */
00087 void StandardSync::addEntry( Syncee* in, Syncee* out, SyncEntry* add )
00088 {
00089     if ( add->id().startsWith("Konnector-") ) {
00090         QString oldId = add->id();
00091         add->setId( in->generateNewId() );
00092         in->insertId( add->type(), oldId, add->id() );
00093         out->insertId( add->type(), oldId, add->id() );
00094     }
00095     out->addEntry( add->clone() );
00096 }
00097 
00098 /*
00099  * Ok we are either modified
00100  * or removed
00101  * Now go through each item and look for one with the
00102  * same uid
00103  * If found check if it was Modified or Removed too
00104  * If yes check if they're equal otherwise
00105  * we need to deconflict
00106  */
00107 void StandardSync::syncSyncEntryListToSyncee(QPtrList<SyncEntry> entries,  Syncee* syncee,
00108                         Syncee* target,
00109                         bool over )
00110 {
00111     kdDebug(5250) << "For All" << endl;
00112     SyncEntry* entry;
00113     SyncEntry* other;
00114     SyncEntry* result;
00115     /* for all modified and deleted*/
00116     for ( entry = entries.first(); entry; entry = entries.next() ) {
00117         result = 0;
00118         other = target->findEntry( entry->id()  );
00119         if (other ) { // exists, should always do
00120         kdDebug(5250) << "Entry 1 " << entry->name() << endl;
00121         kdDebug(5250) << "Entry 2 " << other->name() << endl;
00122 
00123             /* entry modified and other unchanged */
00124             if(entry->wasModified() && other->state()== SyncEntry::Undefined ) {
00125                 kdDebug(5250) << "Modified and unchanged " << endl;
00126                 entry->mergeWith( other );
00127                 target->replaceEntry( other, entry->clone() );
00128             }
00129             /* entry removed and other unchanged or removed too */
00130             else if ( entry->wasRemoved() &&
00131                       other->wasRemoved() ) {
00132                 kdDebug(5250) << "Removed and removed too " << endl;
00133                 // no need for merge
00134                 informBothDeleted( entry, other );
00135                 target->replaceEntry( other, entry->clone() );
00136              /* entry removed and other undefined confirmDelete */
00137             } else if ( entry->wasRemoved() &&
00138                        other->state() == SyncEntry::Undefined ) {
00139                 /* if confirmed that is fairly easy */
00140                 if (confirmDelete(entry, other) )
00141                     target->replaceEntry( other, entry->clone() );
00142                 /*
00143                  * restore by taking the other entry
00144                  * and resetting the state. If the other record is intact
00145                  * maybe we can restore
00146                  */
00147                 else {
00148                   entry = other->clone();
00149                   entry->setState( SyncEntry::Undefined );
00150                 }
00151             }
00152             /* entry was removed and other changed */
00153             else if ( entry->wasRemoved() &&
00154                 other->wasModified() ) {
00155                 kdDebug(5250) << "Entry wasRemoved and other wasModified override is "
00156                           << over << endl;
00157                 result = 0;
00158                 if (!over)
00159                     result = deconflict(entry,other);
00160 
00161                 /*
00162                  * If we do not overwrite and no decision was made
00163                  * then don't sync.
00164                  */
00165                 if (!over && !result ) {
00166                   kdDebug(5250) << "SYNC:   no decision" << endl;
00167                   entry->setDontSync( true );
00168                   other->setDontSync( true );
00169                 }else if (result == entry || over) {
00170                     // no need to merge here, we will remove
00171                     target->replaceEntry(other,entry->clone() );
00172                 }
00173 
00174             } else if ( entry->wasModified() && other->wasModified() ) {
00175                 kdDebug(5250) << "Both where modified and override is" << over<< endl;
00176                 kdDebug(5250) << "Entry1 timestamp " << entry->timestamp() << endl;
00177                 kdDebug(5250) << "Entry2 timestamp " << other->timestamp() << endl;
00178                 kdDebug(5250) << "Equals " << entry->equals( other ) << endl;
00179 
00180                 result = 0l;
00181                 if (!over )
00182                     result = deconflict(entry,other);
00183 
00184                 if (!over && !result ) {
00185                   kdDebug(5250) << "SYNC:   no decision" << endl;
00186                   entry->setDontSync( true );
00187                   other->setDontSync( true );
00188                 }else if (result == entry || over) {
00189                     entry->mergeWith( other );
00190                     target->replaceEntry(other,entry->clone() );
00191                 }
00192             }
00193         } else {
00194         kdDebug(5250) << "added " << endl;
00195             addEntry(syncee, target, entry);
00196         }
00197 
00198     }
00199 }
00200 
KDE Home | KDE Accessibility Home | Description of Access Keys