00001 /* 00002 * Funambol is a mobile platform developed by Funambol, Inc. 00003 * Copyright (C) 2003 - 2007 Funambol, Inc. 00004 * 00005 * This program is free software; you can redistribute it and/or modify it under 00006 * the terms of the GNU Affero General Public License version 3 as published by 00007 * the Free Software Foundation with the addition of the following permission 00008 * added to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED 00009 * WORK IN WHICH THE COPYRIGHT IS OWNED BY FUNAMBOL, FUNAMBOL DISCLAIMS THE 00010 * WARRANTY OF NON INFRINGEMENT OF THIRD PARTY RIGHTS. 00011 * 00012 * This program is distributed in the hope that it will be useful, but WITHOUT 00013 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 00014 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more 00015 * details. 00016 * 00017 * You should have received a copy of the GNU Affero General Public License 00018 * along with this program; if not, see http://www.gnu.org/licenses or write to 00019 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 00020 * MA 02110-1301 USA. 00021 * 00022 * You can contact Funambol, Inc. headquarters at 643 Bair Island Road, Suite 00023 * 305, Redwood City, CA 94063, USA, or at email address info@funambol.com. 00024 * 00025 * The interactive user interfaces in modified source and object code versions 00026 * of this program must display Appropriate Legal Notices, as required under 00027 * Section 5 of the GNU Affero General Public License version 3. 00028 * 00029 * In accordance with Section 7(b) of the GNU Affero General Public License 00030 * version 3, these Appropriate Legal Notices must retain the display of the 00031 * "Powered by Funambol" logo. If the display of the logo is not reasonably 00032 * feasible for technical reasons, the Appropriate Legal Notices must display 00033 * the words "Powered by Funambol". 00034 */ 00035 00036 #ifndef INCL_CACHE_SYNC_SOURCE 00037 #define INCL_CACHE_SYNC_SOURCE 00038 /** @cond API */ 00039 /** @addtogroup Client */ 00040 /** @{ */ 00041 00042 #include "base/fscapi.h" 00043 #include "base/ErrorHandler.h" 00044 #include "base/util/ArrayElement.h" 00045 #include "filter/SourceFilter.h" 00046 #include "spds/constants.h" 00047 #include "spds/SyncItem.h" 00048 #include "spds/SyncStatus.h" 00049 #include "spds/AbstractSyncSourceConfig.h" 00050 #include "spds/SyncSourceReport.h" 00051 #include "spds/SyncSource.h" 00052 #include "syncml/core/TagNames.h" 00053 #include "base/util/Enumeration.h" 00054 #include "base/util/KeyValueStore.h" 00055 #include "base/util/KeyValuePair.h" 00056 00057 BEGIN_NAMESPACE 00058 00059 #define CACHE_FILE_NAME "cache_items.dat" 00060 00061 /** 00062 * This is an extension of the basic SyncSource that a SyncML client developer could implement 00063 * to let the sync engine access the client's data. It provides the logic to retrieve 00064 * the item modification to be exchanged with the server 00065 */ 00066 class CacheSyncSource : public SyncSource { 00067 00068 private: 00069 00070 /** 00071 * Used to store a KeyValuePair containing the key and the command 00072 * associated to the item. It stores the cache: 00073 * - during the slow sync. After the allKeys is populated, for every 00074 * item status sent back by the server, the cache is populated. It is possible 00075 * to write down when needed. 00076 * - during the two-way sync it is populated at the beginning to understand 00077 * the modification. This action populates the newKeys, updatedKeys and deletedKeys. 00078 * For every item status sent back by the server the cache is updated 00079 * 00080 */ 00081 KeyValueStore* cache; 00082 00083 /** 00084 * Enumeration of the new keys 00085 */ 00086 Enumeration* newKeys; 00087 /** 00088 * Enumeration of the updated keys 00089 */ 00090 Enumeration* updatedKeys; 00091 /** 00092 * Enumeration of the deleted keys 00093 */ 00094 Enumeration* deletedKeys; 00095 00096 /** 00097 * Used to store the keys of all items for a slow based sync 00098 * It is an enumeration of StringBuffer keys 00099 */ 00100 Enumeration* allKeys; 00101 00102 /** 00103 * Fills the sync item given the key. It is used by the method getXXXItem to 00104 * complete the SyncItem. 00105 */ 00106 SyncItem* fillSyncItem(StringBuffer* key); 00107 00108 /** 00109 * The way to calculate the cache is the follow: 00110 * loop on the current element against an array list 00111 * that has the cache. It is the copy of the original cache. 00112 * When an current element is found in the cache, it is removed 00113 * from the cache copy. At the end the remained element 00114 * in the cache are the deleted ones. 00115 * Called when the two-way sync is requested 00116 */ 00117 bool fillItemModifications(); 00118 00119 /** 00120 * Utility private method that populates the keyValuePair with 00121 * the couple key/signature starting from the SyncItem. 00122 * Used in the addItem and updateItem 00123 * 00124 * @param item - IN: the SyncItem 00125 * @param kvp - OUT: the KeyValuePair to be populate 00126 */ 00127 void getKeyAndSignature(SyncItem& item, KeyValuePair& kvp); 00128 00129 protected: 00130 00131 /** 00132 * Save the current cache in what is implemented by KeyValueStore (a file or wathever). 00133 */ 00134 int saveCache(); 00135 00136 /** 00137 * Called by the sync engine to add an item that the server has sent. 00138 * The implementation calls the insertItem method that must be implemented 00139 * by the user. Also used to update the item 00140 */ 00141 int addItem(SyncItem& item); 00142 00143 /** 00144 * Called by the sync engine to update an item that the source already 00145 * should have. The item's key is the local key of that item. 00146 * 00147 * @param item the item as sent by the server 00148 * @return SyncML status code 00149 */ 00150 int updateItem(SyncItem& item); 00151 00152 /** 00153 * Called by the sync engine to update an item that the source already 00154 * should have. The item's key is the local key of that item, no data is 00155 * provided. 00156 * 00157 * @param item the item as sent by the server 00158 */ 00159 int deleteItem(SyncItem& item); 00160 00161 /** 00162 * Used to update the cache adding, replacing or deleting. 00163 * The KeyValuePair contains the pair UID/signature. It is provided 00164 * by the proper method who calls this. It udpates the cache 00165 * that is in memory. 00166 * The action by default is Replace. 00167 */ 00168 int updateInCache(KeyValuePair& k, const char* action = REPLACE); 00169 00170 /** 00171 * To insert in the cache. 00172 */ 00173 int insertInCache(KeyValuePair& k) { 00174 return updateInCache(k, ADD); 00175 } 00176 00177 /** 00178 * To remove from cache 00179 */ 00180 int removeFromCache(KeyValuePair& k) { 00181 return updateInCache(k, DEL); 00182 } 00183 00184 public: 00185 00186 /** 00187 * Constructor: create a CacheSyncSource with the specified name 00188 * 00189 * @param name the name of the SyncSource 00190 * @param sc configuration for the sync source: the instance 00191 * must remain valid throughout the lifetime of the 00192 * sync source because it keeps a reference to it 00193 * and uses it as its own. A NULL pointer is allowed 00194 * for unit testing outside of the sync framework; 00195 * the sync source then references a global config 00196 * instance to avoid crashes, but modifying that config 00197 * will not make much sense. The pointer may also be 00198 * set directly after creating the SyncSource, which 00199 * is useful when a derived class creates the config 00200 * in its own constructor. 00201 * @param cache the store for the cache. Released by the CacheSyncSource 00202 * 00203 */ 00204 CacheSyncSource(const WCHAR* name, AbstractSyncSourceConfig* sc, 00205 KeyValueStore* cache = NULL); 00206 00207 // Destructor 00208 virtual ~CacheSyncSource(); 00209 00210 /** 00211 * called by the sync engine with the status returned by the 00212 * server for a certain item that the client sent to the server. 00213 * It contains also the proper command associated to the item. 00214 * It is used to update the current array of cache. 00215 * 00216 * @param key - the local key of the item 00217 * @param status - the SyncML status returned by the server 00218 * @param command - the SyncML command associated to the item 00219 * 00220 */ 00221 void setItemStatus(const WCHAR* key, int status, const char* command); 00222 00223 /** 00224 * Return the key of the first SyncItem of all. 00225 * It is used in case of refresh sync 00226 * and retrieve all the keys of the data source. 00227 * @deprecated no more used. use removeAllItems instead. 00228 */ 00229 SyncItem* getFirstItemKey() { return NULL; }; 00230 00231 /** 00232 * Return the key of the next SyncItem of all. 00233 * It is used in case of refresh sync 00234 * and retrieve all the keys of the data source. 00235 * @deprecated no more used. use removeAllItems instead. 00236 */ 00237 SyncItem* getNextItemKey() { return NULL; }; 00238 00239 /** 00240 * Return the first SyncItem of all. 00241 * It is used in case of slow sync 00242 * and retrieve the entire data source content. 00243 */ 00244 SyncItem* getFirstItem(); 00245 00246 /** 00247 * Return the next SyncItem of all. 00248 * It is used in case of slow sync 00249 * and retrieve the entire data source content. 00250 */ 00251 SyncItem* getNextItem(); 00252 00253 /** 00254 * Return the first SyncItem of new one. It is used in case of fast sync 00255 * and retrieve the new data source content. 00256 */ 00257 SyncItem* getFirstNewItem(); 00258 00259 /** 00260 * Return the next SyncItem of new one. It is used in case of fast sync 00261 * and retrieve the new data source content. 00262 */ 00263 SyncItem* getNextNewItem(); 00264 00265 /** 00266 * Return the first SyncItem of updated one. It is used in case of fast sync 00267 * and retrieve the new data source content. 00268 */ 00269 SyncItem* getFirstUpdatedItem(); 00270 00271 /** 00272 * Return the next SyncItem of updated one. It is used in case of fast sync 00273 * and retrieve the new data source content. 00274 */ 00275 SyncItem* getNextUpdatedItem(); 00276 00277 /** 00278 * Return the first SyncItem of updated one. It is used in case of fast sync 00279 * and retrieve the new data source content. 00280 */ 00281 SyncItem* getFirstDeletedItem(); 00282 00283 /** 00284 * Return the next SyncItem of updated one. It is used in case of fast sync 00285 * and retrieve the new data source content. 00286 */ 00287 SyncItem* getNextDeletedItem(); 00288 00289 /** 00290 * Indicates that all the server status of the current package 00291 * of the client items has been processed by the engine. 00292 * This signal can be useful to update the modification arrays 00293 * NOT USED at the moment 00294 */ 00295 void serverStatusPackageEnded() {}; 00296 00297 /** 00298 * Indicates that all the client status of the current package 00299 * of the server items that has been processed by the client and 00300 * are going to be sent to the server. 00301 * This signal can be useful to update the modification arrays 00302 * NOT USED at the moment 00303 */ 00304 void clientStatusPackageEnded() {}; 00305 00306 /** 00307 * In the first implementatation, in which serverStatusPackageEnded and 00308 * clientStatusPackageEnded are not yet impelemented, the end sync 00309 * will udpate the whole cache status persistently. 00310 */ 00311 int endSync(); 00312 00313 /** 00314 * Get the signature of an item given the key. The signature could be 00315 * a crc computation or a timestamp or whatever can identify uniquely the 00316 * content of an item. The default implementation uses a 00317 * crc computation of the value. Overriding implementation could provide 00318 * something different like the timestamp or other... 00319 * 00320 * @param key the key of the item. 00321 * @return the signature of the selected item 00322 */ 00323 virtual StringBuffer getItemSignature(StringBuffer& key); 00324 00325 /** 00326 * Get the content of an item given the key. It is used to populate 00327 * the SyncItem before the engine uses it in the usual flow of the sync. 00328 * 00329 * @param key the local key of the item 00330 * @param size OUT: the size of the content 00331 */ 00332 virtual void* getItemContent(StringBuffer& key, size_t* size) = 0; 00333 00334 00335 /** 00336 * Get an array list containing all the StringBuffer keys of all items. 00337 * Used for the sync requiring and exchange of all items and 00338 * for the sync that need to calculate the modification. 00339 * It has to return a new allocated Enumeration that is 00340 * freed by the CacheSyncSource 00341 */ 00342 virtual Enumeration* getAllItemList() = 0; 00343 00344 /** 00345 * Called by the sync engine to add an item that the server has sent. 00346 * The sync source is expected to add it to its database, then set the 00347 * key to the local key assigned to the new item. Alternatively 00348 * the sync source can match the new item against one of the existing 00349 * items and return that key. 00350 * 00351 * @param item the item as sent by the server 00352 * @return SyncML status code 00353 */ 00354 virtual int insertItem(SyncItem& item) = 0; 00355 00356 /** 00357 * Called by the sync engine to update an item that the source already 00358 * should have. The item's key is the local key of that item. 00359 * 00360 * @param item the item as sent by the server 00361 * @return SyncML status code 00362 */ 00363 virtual int modifyItem(SyncItem& item) = 0; 00364 00365 /** 00366 * Called by the sync engine to update an item that the source already 00367 * should have. The item's key is the local key of that item, no data is 00368 * provided. 00369 * 00370 * @param item the item as sent by the server 00371 */ 00372 virtual int removeItem(SyncItem& item) = 0; 00373 00374 00375 }; 00376 00377 END_NAMESPACE 00378 00379 /** @} */ 00380 /** @endcond */ 00381 #endif