Changeset 113 for Mulberry/branches/v4.1d1/Sources_Common/Calendar_Store/Protocols/CCalendarProtocol.cpp
- Timestamp:
- 10/28/07 23:41:34 (1 year ago)
- Files:
-
- 1 modified
Legend:
- Unmodified
- Added
- Removed
-
Mulberry/branches/v4.1d1/Sources_Common/Calendar_Store/Protocols/CCalendarProtocol.cpp
r86 r113 32 32 #include "CConnectionManager.h" 33 33 #include "CLocalCalendarClient.h" 34 #include "CPasswordManager.h" 34 35 #include "CPreferences.h" 35 36 #include "CWebDAVCalendarClient.h" … … 38 39 39 40 #include "CICalendarSync.h" 41 #include "CICalendarDateTime.h" 42 #include "CICalendarDuration.h" 40 43 41 44 #include "XMLDocument.h" … … 60 63 mCacheIsPrimary = false; 61 64 mSyncingList = false; 65 mListedFromCache = false; 62 66 63 67 // Only WebDAV servers can disconnect … … 482 486 // Only bother if it contains something 483 487 if (!auth->GetPswd().empty()) 488 { 484 489 CCalendarProtocol::SetCachedPswd(auth->GetUID(), auth->GetPswd()); 490 CPasswordManager::GetManager()->AddPassword(GetAccount(), auth->GetPswd()); 491 } 485 492 } 486 493 … … 569 576 else 570 577 { 571 // Now get new list 572 mClient->_ListCalendars(&mStoreRoot); 573 574 // Always keep disconnected cache list in sync with server 575 if (mCacheClient != NULL) 576 { 577 DumpCalendars(); 578 } 578 // First try the disconnected cache - but only use if current 579 if (mListedFromCache || ((mCacheClient == NULL) || !ReadCalendars(true))) 580 { 581 // Now get new list 582 mClient->_ListCalendars(&mStoreRoot); 583 584 // Always keep disconnected cache list in sync with server 585 if (mCacheClient != NULL) 586 { 587 DumpCalendars(); 588 } 589 } 590 else 591 mListedFromCache = true; 579 592 } 580 593 … … 1006 1019 // 2.1 Add new components to server and cache info 1007 1020 // 2.2 Remove deleted components from server and cached server info if still present on server 1008 // 2.3 Cache info for changed items for later sync 1021 // 2.3 Cache info for changed items for later sync (or change them immediately if the server has not changed 1009 1022 // 1010 1023 // 3. Scan list of local components … … 1020 1033 // 4. Copy remaining items in server set to local cache - they are new items 1021 1034 // 1035 // We only need to do steps 3 & 4 if the data on the server is known to have changed. 1036 // 1022 1037 1023 1038 // Now do it... … … 1025 1040 // Step 1 1026 1041 cdstrmap comps; 1027 mClient->_GetComponentInfo(node, cal, comps); 1042 bool server_changed = mClient->_CalendarChanged(node, cal); 1043 if (server_changed) 1044 mClient->_GetComponentInfo(node, cal, comps); 1045 else 1046 { 1047 mCacheClient->_ReadFullCalendar(node, cal); 1048 } 1028 1049 1029 1050 // Step 2 … … 1063 1084 // Step 2.3 1064 1085 else if ((*iter).second.GetAction() == iCal::CICalendarComponentRecord::eChanged) 1065 cache_changed.insert(cdstrmap::value_type((*iter).second.GetRURL(), (*iter).second.GetETag())); 1086 { 1087 if (server_changed) 1088 cache_changed.insert(cdstrmap::value_type((*iter).second.GetRURL(), (*iter).second.GetETag())); 1089 else 1090 { 1091 // Change it on the server 1092 const iCal::CICalendarComponent* comp = cal.GetComponentByKey((*iter).first); 1093 mClient->_ChangeComponent(node, cal, *comp); 1094 cache_changed.insert(cdstrmap::value_type((*iter).second.GetRURL(), (*iter).second.GetETag())); 1095 } 1096 } 1066 1097 } 1067 1098 1068 1099 1069 1100 // Now do sync 1070 1071 // Get component info from cache 1072 iCal::CICalendarComponentDBList dbs; 1073 cal.GetAllDBs(dbs); 1074 cdstrvect component_keys; 1075 for(iCal::CICalendarComponentDBList::const_iterator iter1 = dbs.begin(); iter1 != dbs.end(); iter1++) 1076 { 1077 for(iCal::CICalendarComponentDB::const_iterator iter2 = (*iter1)->begin(); iter2 != (*iter1)->end(); iter2++) 1101 if (server_changed) 1102 { 1103 // Get component info from cache 1104 iCal::CICalendarComponentDBList dbs; 1105 cal.GetAllDBs(dbs); 1106 cdstrvect component_keys; 1107 for(iCal::CICalendarComponentDBList::const_iterator iter1 = dbs.begin(); iter1 != dbs.end(); iter1++) 1078 1108 { 1079 component_keys.push_back((*iter2).second->GetMapKey()); 1109 for(iCal::CICalendarComponentDB::const_iterator iter2 = (*iter1)->begin(); iter2 != (*iter1)->end(); iter2++) 1110 { 1111 component_keys.push_back((*iter2).second->GetMapKey()); 1112 } 1080 1113 } 1081 }1082 1083 // Step 31084 cdstrset matching_components;1085 for(cdstrvect::const_iterator iter = component_keys.begin(); iter != component_keys.end(); iter++)1086 {1087 iCal::CICalendarComponent* cache_comp = cal.GetComponentByKey(*iter);1088 if (cache_comp == NULL)1089 continue;1090 1091 // Get this components RURL1092 cdstring cache_rurl = cache_comp->GetRURL();1093 cdstring cache_etag = cache_comp->GetETag();1094 1114 1095 // Get the server info 1096 cdstring server_rurl; 1097 cdstring server_etag; 1098 cdstrmap::const_iterator found = comps.find(cache_rurl); 1099 if (found != comps.end()) 1115 // Step 3 1116 cdstrset matching_components; 1117 for(cdstrvect::const_iterator iter = component_keys.begin(); iter != component_keys.end(); iter++) 1100 1118 { 1101 server_rurl = (*found).first;1102 server_etag = (*found).second;1103 }1104 1105 // Step 3.11106 if (cache_added.count(cache_rurl) != 0)1107 c ontinue;1108 1109 // Step 3.21110 else if (cache_changed.count(cache_rurl) != 0)1111 {1112 // Step 3.2.11113 if ( cache_etag == server_etag)1119 iCal::CICalendarComponent* cache_comp = cal.GetComponentByKey(*iter); 1120 if (cache_comp == NULL) 1121 continue; 1122 1123 // Get this components RURL 1124 cdstring cache_rurl = cache_comp->GetRURL(); 1125 cdstring cache_etag = cache_comp->GetETag(); 1126 1127 // Get the server info 1128 cdstring server_rurl; 1129 cdstring server_etag; 1130 cdstrmap::const_iterator found = comps.find(cache_rurl); 1131 if (found != comps.end()) 1114 1132 { 1115 // Write changed cache component to server1116 mClient->_ChangeComponent(node, cal, *cache_comp);1133 server_rurl = (*found).first; 1134 server_etag = (*found).second; 1117 1135 } 1136 1137 // Step 3.1 1138 if (cache_added.count(cache_rurl) != 0) 1139 continue; 1118 1140 1119 // Step 3.2 .21120 else 1141 // Step 3.2 1142 else if (cache_changed.count(cache_rurl) != 0) 1121 1143 { 1122 // Do iCal SEQ etc comparison 1144 // Step 3.2.1 1145 if (cache_etag == server_etag) 1146 { 1147 // Write changed cache component to server 1148 mClient->_ChangeComponent(node, cal, *cache_comp); 1149 } 1123 1150 1124 // First read in component from server into temp calendar 1125 iCal::CICalendar tempcal; 1126 iCal::CICalendarComponent* server_comp = mClient->_ReadComponent(node, tempcal, server_rurl); 1127 if (server_comp != NULL) 1151 // Step 3.2.2 1152 else 1128 1153 { 1129 int result = iCal::CICalendarSync::CompareComponentVersions(server_comp, cache_comp);1154 // Do iCal SEQ etc comparison 1130 1155 1131 if (result == 1) 1156 // First read in component from server into temp calendar 1157 iCal::CICalendar tempcal; 1158 iCal::CICalendarComponent* server_comp = mClient->_ReadComponent(node, tempcal, server_rurl); 1159 if (server_comp != NULL) 1132 1160 { 1133 // Cache is newer than server - cache overwrites to server 1134 mClient->_ChangeComponent(node, cal, *cache_comp); 1135 } 1136 else if (result == -1) 1137 { 1138 // Cache is older than server - server overwrites cache 1139 1140 // Remove the cached component first 1141 cal.RemoveComponentByKey(cache_comp->GetMapKey()); 1142 cache_comp = NULL; 1161 int result = iCal::CICalendarSync::CompareComponentVersions(server_comp, cache_comp); 1143 1162 1144 // Copy component from server into local cache effectively replacing old one 1145 iCal::CICalendarComponent* new_comp = server_comp->clone(); 1146 new_comp->SetCalendar(cal.GetRef()); 1147 cal.AddComponent(new_comp); 1163 if (result == 1) 1164 { 1165 // Cache is newer than server - cache overwrites to server 1166 mClient->_ChangeComponent(node, cal, *cache_comp); 1167 } 1168 else if (result == -1) 1169 { 1170 // Cache is older than server - server overwrites cache 1171 1172 // Remove the cached component first 1173 cal.RemoveComponentByKey(cache_comp->GetMapKey()); 1174 cache_comp = NULL; 1175 1176 // Copy component from server into local cache effectively replacing old one 1177 iCal::CICalendarComponent* new_comp = server_comp->clone(); 1178 new_comp->SetCalendar(cal.GetRef()); 1179 cal.AddComponent(new_comp); 1180 } 1148 1181 } 1149 1182 } 1150 1183 } 1184 1185 // Step 3.3 1186 else if (!server_rurl.empty()) 1187 { 1188 // Step 3.3.1 1189 if (cache_etag != server_etag) 1190 { 1191 // Copy from server to cache overwriting cache value 1192 1193 // Remove the cached component first 1194 cal.RemoveComponentByKey(cache_comp->GetMapKey()); 1195 cache_comp = NULL; 1196 1197 // Read component from server into local cache effectively replacing old one 1198 mClient->_ReadComponent(node, cal, server_rurl); 1199 } 1200 } 1201 1202 // Step 3.4 1203 else 1204 { 1205 // comp is deleted in this call 1206 cal.RemoveComponentByKey(cache_comp->GetMapKey()); 1207 cache_comp = NULL; 1208 } 1209 1210 // Step 3.5 1211 if (!server_rurl.empty()) 1212 matching_components.insert(server_rurl); 1151 1213 } 1152 1214 1153 // Step 3.3 1154 else if (!server_rurl.empty()) 1215 // Step 4 1216 cdstrvect rurls; 1217 for(cdstrmap::const_iterator iter = comps.begin(); iter != comps.end(); iter++) 1155 1218 { 1156 // Step 3.3.1 1157 if (cache_etag != server_etag) 1158 { 1159 // Copy from server to cache overwriting cache value 1160 1161 // Remove the cached component first 1162 cal.RemoveComponentByKey(cache_comp->GetMapKey()); 1163 cache_comp = NULL; 1164 1165 // Read component from server into local cache effectively replacing old one 1166 mClient->_ReadComponent(node, cal, server_rurl); 1167 } 1219 cdstrset::const_iterator found = matching_components.find((*iter).first); 1220 if (found == matching_components.end()) 1221 rurls.push_back((*iter).first); 1168 1222 } 1169 1170 // Step 3.4 1171 else 1172 { 1173 // comp is deleted in this call 1174 cal.RemoveComponentByKey(cache_comp->GetMapKey()); 1175 cache_comp = NULL; 1176 } 1177 1178 // Step 3.5 1179 if (!server_rurl.empty()) 1180 matching_components.insert(server_rurl); 1181 } 1182 1183 // Step 4 1184 cdstrvect rurls; 1185 for(cdstrmap::const_iterator iter = comps.begin(); iter != comps.end(); iter++) 1186 { 1187 cdstrset::const_iterator found = matching_components.find((*iter).first); 1188 if (found == matching_components.end()) 1189 rurls.push_back((*iter).first); 1190 } 1191 1192 // Read components from server into local cache as its a new one on the server 1193 if (rurls.size() != 0) 1194 mClient->_ReadComponents(node, cal, rurls); 1223 1224 // Read components from server into local cache as its a new one on the server 1225 if (rurls.size() != 0) 1226 mClient->_ReadComponents(node, cal, rurls); 1227 } 1195 1228 1196 1229 // Clear out cache recording 1197 1230 cal.ClearRecording(); 1198 1231 1232 // Get the current server sync token 1233 mClient->_UpdateSyncToken(node, cal); 1234 1199 1235 // Now write back cache 1200 if ( mCacheClient->_TouchCalendar(node))1236 if (!mCacheClient->_TouchCalendar(node)) 1201 1237 DumpCalendars(); 1202 1238 mCacheClient->_WriteFullCalendar(node, cal); … … 1742 1778 xmllib::XMLObject::WriteAttribute(doc->GetRoot(), cXMLAttribute_version, (uint32_t)1); 1743 1779 1780 // Store the current date 1781 iCal::CICalendarDateTime dt = iCal::CICalendarDateTime::GetNowUTC(); 1782 dt.SetDateOnly(true); 1783 xmllib::XMLObject::WriteAttribute(doc->GetRoot(), cXMLAttribute_datestamp, dt.GetText()); 1784 1744 1785 // Now add each node (and child nodes) to XML doc 1745 1786 mStoreRoot.WriteXML(doc.get(), doc->GetRoot(), true); … … 1750 1791 } 1751 1792 1752 void CCalendarProtocol::ReadCalendars() 1753 { 1793 bool CCalendarProtocol::ReadCalendars(bool only_if_current) 1794 { 1795 bool is_current = false; 1754 1796 cdstring list_name = mOfflineCWD + cCalendarListName; 1755 1797 … … 1764 1806 xmllib::XMLNode* root = parser.Document()->GetRoot(); 1765 1807 if (!root->CompareFullName(cXMLElement_calendarlist)) 1766 return ;1808 return is_current; 1767 1809 1768 // Now have store root read in all children 1769 mStoreRoot.ReadXML(root, true); 1770 1771 // Always cache the disconnected state 1772 mStoreRoot.TestDisconnectCache(); 1773 } 1774 } 1810 // Get the datestamp 1811 cdstring dtstamp; 1812 if (xmllib::XMLObject::ReadAttribute(root, cXMLAttribute_datestamp, dtstamp)) 1813 { 1814 iCal::CICalendarDateTime dtnow = iCal::CICalendarDateTime::GetNowUTC(); 1815 dtnow.SetDateOnly(true); 1816 1817 iCal::CICalendarDateTime dt; 1818 dt.Parse(dtstamp); 1819 1820 iCal::CICalendarDuration diff = dtnow - dt; 1821 is_current = (diff.GetTotalSeconds() <= 48 * 60 * 60); 1822 } 1823 1824 if (!only_if_current || is_current) 1825 { 1826 // Now have store root read in all children 1827 mStoreRoot.ReadXML(root, true); 1828 1829 // Always cache the disconnected state 1830 if (IsDisconnected() || mCacheIsPrimary) 1831 mStoreRoot.TestDisconnectCache(); 1832 } 1833 } 1834 1835 return is_current; 1836 }