00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <kdebug.h>
00023
00024 #include <syncee.h>
00025
00026 #include "syncalgo.h"
00027
00028 using namespace KSync;
00029
00030 PIMSyncAlg::PIMSyncAlg( SyncUi* ui )
00031 : SyncAlgorithm( ui )
00032 {
00033 }
00034
00035 PIMSyncAlg::~PIMSyncAlg()
00036 {
00037 }
00038
00039
00040
00041
00042
00043 void PIMSyncAlg::syncToTarget( Syncee* syncee,
00044 Syncee* target,
00045 bool override)
00046 {
00047 if (syncee->syncMode() == Syncee::MetaLess ||
00048 syncee->firstSync() )
00049 return syncFirst(syncee, target, override);
00050 else if ( target->syncMode() == Syncee::MetaLess ||
00051 target->firstSync() )
00052 return syncFirst( syncee, target, override );
00053 else
00054 return syncMeta( syncee, target, override );
00055 }
00056
00057
00058
00059
00060
00061 void PIMSyncAlg::syncFirst( Syncee* syncee,
00062 Syncee* target,
00063 bool override )
00064 {
00065 kdDebug(5231) << "SyncFirst " << endl;
00066 SyncEntry *targetEntry = 0l;
00067
00068
00069 SyncEntry *sourceEntry = syncee->firstEntry();
00070
00071 while (sourceEntry) {
00072
00073 if ( sourceEntry->state() == SyncEntry::Removed ) {
00074 kdDebug(5231) << "Entry removed " << sourceEntry->name() << endl;
00075 sourceEntry = syncee->nextEntry();
00076 continue;
00077 }
00078
00079
00080 targetEntry = 0l;
00081 targetEntry = target->findEntry(sourceEntry->id());
00082
00083
00084 if (targetEntry) {
00085 kdDebug(5231) << "Found target " << endl;
00086
00087 if (sourceEntry->equals(targetEntry)) {
00088 kdDebug(5231) << "No action required" << endl;
00089
00090 } else {
00091
00092 if (override && targetEntry->state() != SyncEntry::Removed ) {
00093
00094 kdDebug(5231) << "overriding and merging!" << endl;
00095
00096 sourceEntry->mergeWith( targetEntry );
00097 target->replaceEntry(targetEntry,sourceEntry->clone() );
00098 } else {
00099 if (syncee->hasChanged(sourceEntry) &&
00100 target->hasChanged(targetEntry)) {
00101 kdDebug(5231) << "Deconflict " << endl;
00102 kdDebug(5231) << "Entry 1 state: " << sourceEntry->state() << endl;
00103 kdDebug(5231) << "Entry 2 state: " << targetEntry->state() << endl;
00104
00105 SyncEntry *result = deconflict(sourceEntry,targetEntry);
00106 if (result == sourceEntry) {
00107 kdDebug(5231) << "Merging and then replacing!" << endl;
00108 sourceEntry->mergeWith( targetEntry );
00109 target->replaceEntry(targetEntry,sourceEntry->clone() );
00110 }else
00111 targetEntry->mergeWith( sourceEntry );
00112
00113 } else if (syncee->hasChanged(sourceEntry) &&
00114 !target->hasChanged(targetEntry)) {
00115
00116 kdDebug(5231) << "Take source entry" << endl;
00117 sourceEntry->mergeWith( targetEntry );
00118 target->replaceEntry(targetEntry,sourceEntry->clone() );
00119 } else if (!syncee->hasChanged(sourceEntry) &&
00120 target->hasChanged(targetEntry)) {
00121
00122 kdDebug(5231) << "Take target entry" << endl;
00123 targetEntry->mergeWith(sourceEntry);
00124 }
00125 }
00126 }
00127 } else {
00128
00129 kdDebug(5231) << "adding target " << endl;
00130 addEntry( syncee, target, sourceEntry );
00131 }
00132 sourceEntry = syncee->nextEntry();
00133 }
00134 }
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147 void PIMSyncAlg::syncMeta( Syncee* syncee,
00148 Syncee* target,
00149 bool over )
00150 {
00151 kdDebug(5231) << "SyncMeta " << endl;
00152 QPtrList<SyncEntry> entries = syncee->added();
00153 SyncEntry* entry;
00154 SyncEntry* targetEntry;
00155
00156 for ( entry = entries.first(); entry; entry = entries.next() ) {
00157
00158 targetEntry = target->findEntry( entry->id() );
00159 kdDebug(5231) << "About to add " << entry->name() << endl;
00160 if(!targetEntry ){
00161 kdDebug(5231) << "Not added before " << endl;
00162 addEntry( syncee, target, entry );
00163 }else {
00164 kdDebug(5231) << "Added before " << endl;
00165 }
00166 }
00167
00168 forAll( syncee->modified(), syncee, target, over );
00169 forAll( syncee->removed(), syncee, target,over );
00170
00171 }
00172
00173 void PIMSyncAlg::addEntry( Syncee* in, Syncee* out, SyncEntry* add )
00174 {
00175 if ( add->id().startsWith("Konnector-") ) {
00176 QString oldId = add->id();
00177 add->setId( in->newId() );
00178 in->insertId( add->type(), oldId, add->id() );
00179 out->insertId( add->type(), oldId, add->id() );
00180 }
00181 out->addEntry( add->clone() );
00182 }
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193 void PIMSyncAlg::forAll(QPtrList<SyncEntry> entries, Syncee* syncee,
00194 Syncee* target,
00195 bool over )
00196 {
00197 kdDebug(5231) << "For All" << endl;
00198 SyncEntry* entry;
00199 SyncEntry* other;
00200 SyncEntry* result;
00201
00202 for ( entry = entries.first(); entry; entry = entries.next() ) {
00203 result = 0;
00204 other = target->findEntry( entry->id() );
00205 if (other ) {
00206 kdDebug(5231) << "Entry 1 " << entry->name() << endl;
00207 kdDebug(5231) << "Entry 2 " << other->name() << endl;
00208
00209
00210 if(entry->wasModified() && other->state()== SyncEntry::Undefined ) {
00211 kdDebug(5231) << "Modified and unchanged " << endl;
00212 entry->mergeWith( other );
00213 target->replaceEntry( other, entry->clone() );
00214 }
00215
00216 else if ( entry->wasRemoved() &&
00217 other->wasRemoved() ) {
00218 kdDebug(5231) << "Removed and removed too " << endl;
00219
00220 informBothDeleted( entry, other );
00221 target->replaceEntry( other, entry->clone() );
00222
00223 } else if ( entry->wasRemoved() &&
00224 other->state() == SyncEntry::Undefined ) {
00225
00226 if (confirmDelete(entry, other) )
00227 target->replaceEntry( other, entry->clone() );
00228
00229
00230
00231
00232
00233
00234
00235 else {
00236 QBitArray ar = entry->syncee()->bitArray();
00237 QBitArray oth;
00238 oth.fill( false, ar.size() );
00239 entry->syncee()->setSupports( oth );
00240
00241 entry->mergeWith( other );
00242
00243
00244
00245
00246
00247
00248
00249 if (!over ) {
00250 entry->setState( SyncEntry::Undefined );
00251 other->setState( SyncEntry::Modified);
00252 } else
00253 entry->setState( SyncEntry::Modified);
00254
00255
00256 entry->syncee()->setSupports( ar );
00257 }
00258 }
00259
00260 else if ( entry->wasRemoved() &&
00261 other->wasModified() ) {
00262 kdDebug(5231) << "Entry wasRemoved and other wasModified override is "
00263 << over << endl;
00264 if (!over)
00265 result = deconflict(entry,other);
00266 if (result == entry || over) {
00267
00268 target->replaceEntry(other,entry->clone() );
00269 }
00270
00271 } else if ( entry->wasModified() && other->wasModified() ) {
00272 kdDebug(5231) << "Both where modified override" << over<< endl;
00273 kdDebug(5231) << "Entry1 timestamp " << entry->timestamp() << endl;
00274 kdDebug(5231) << "Entry2 timestamp " << other->timestamp() << endl;
00275 kdDebug(5231) << "Equals " << entry->equals( other ) << endl;
00276
00277 if (!over )
00278 result = deconflict(entry,other);
00279
00280 if (result == entry || over) {
00281 entry->mergeWith( other );
00282 target->replaceEntry(other,entry->clone() );
00283 }
00284
00285 }
00286
00287 } else {
00288 kdDebug(5231) << "added " << endl;
00289 addEntry(syncee, target, entry);
00290 }
00291
00292 }
00293 }