1ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmann// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmann// Use of this source code is governed by a BSD-style license that can be 3ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmann// found in the LICENSE file. 4ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmann 55592142cb9383df0556b27ac59e96547b380310bJohan Hedberg#ifndef CHROME_BROWSER_SYNC_GLUE_BOOKMARK_MODEL_ASSOCIATOR_H_ 69184e2eeb7b97371c6b83b747c8984e2340d2b47Marcel Holtmann#define CHROME_BROWSER_SYNC_GLUE_BOOKMARK_MODEL_ASSOCIATOR_H_ 7ad868bd4137e86fbf141175f411898796287ff2aBrad Midgley#pragma once 8ad868bd4137e86fbf141175f411898796287ff2aBrad Midgley 9ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmann#include <map> 10ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmann#include <set> 11ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmann#include <string> 12ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmann 13ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmann#include "base/basictypes.h" 14ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmann#include "base/task.h" 15ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmann#include "chrome/browser/sync/unrecoverable_error_handler.h" 16ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmann#include "chrome/browser/sync/glue/model_associator.h" 17ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmann 18ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmannclass BookmarkModel; 19ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmannclass BookmarkNode; 20ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmann 21ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmannnamespace sync_api { 22ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmannclass BaseNode; 23ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmannclass BaseTransaction; 24ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmannclass ReadNode; 25ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmannstruct UserShare; 26ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmann} 27ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmann 28ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmannnamespace browser_sync { 29ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmann 30ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmannclass BookmarkChangeProcessor; 31ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmann 32ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmann// Contains all model association related logic: 33ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmann// * Algorithm to associate bookmark model and sync model. 34ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmann// * Methods to get a bookmark node for a given sync node and vice versa. 35ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmann// * Persisting model associations and loading them back. 36ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmannclass BookmarkModelAssociator 37ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmann : public PerDataTypeAssociatorInterface<BookmarkNode, int64> { 38ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmann public: 39ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmann static syncable::ModelType model_type() { return syncable::BOOKMARKS; } 40ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmann BookmarkModelAssociator( 41ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmann BookmarkModel* bookmark_model, 42ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmann sync_api::UserShare* user_share, 4340e63b5f546f8b486c7ec99570eb805ad4afc923Marcel Holtmann UnrecoverableErrorHandler* unrecoverable_error_handler); 44ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmann virtual ~BookmarkModelAssociator(); 45ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmann 46ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmann // AssociatorInterface implementation. 47ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmann // 48ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmann // AssociateModels iterates through both the sync and the browser 49ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmann // bookmark model, looking for matched pairs of items. For any pairs it 50ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmann // finds, it will call AssociateSyncID. For any unmatched items, 51ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmann // MergeAndAssociateModels will try to repair the match, e.g. by adding a new 52ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmann // node. After successful completion, the models should be identical and 53ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmann // corresponding. Returns true on success. On failure of this step, we 54ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmann // should abort the sync operation and report an error to the user. 55ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmann virtual bool AssociateModels(); 56ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmann 57ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmann virtual bool DisassociateModels(); 58ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmann 59ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmann // The has_nodes out param is true if the sync model has nodes other 60ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmann // than the permanent tagged nodes. 61ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmann virtual bool SyncModelHasUserCreatedNodes(bool* has_nodes); 62ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmann 63ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmann // Returns sync id for the given bookmark node id. 64ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmann // Returns sync_api::kInvalidId if the sync node is not found for the given 65ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmann // bookmark node id. 66ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmann virtual int64 GetSyncIdFromChromeId(const int64& node_id); 67ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmann 68ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmann // Returns the bookmark node for the given sync id. 69ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmann // Returns NULL if no bookmark node is found for the given sync id. 70ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmann virtual const BookmarkNode* GetChromeNodeFromSyncId(int64 sync_id); 71ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmann 72ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmann // Initializes the given sync node from the given bookmark node id. 73ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmann // Returns false if no sync node was found for the given bookmark node id or 74ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmann // if the initialization of sync node fails. 75ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmann virtual bool InitSyncNodeFromChromeId(const int64& node_id, 76ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmann sync_api::BaseNode* sync_node); 77ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmann 78ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmann // Associates the given bookmark node with the given sync id. 79ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmann virtual void Associate(const BookmarkNode* node, int64 sync_id); 80ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmann // Remove the association that corresponds to the given sync id. 81ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmann virtual void Disassociate(int64 sync_id); 82ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmann 83ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmann virtual void AbortAssociation() { 84ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmann // No implementation needed, this associator runs on the main 85ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmann // thread. 86ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmann } 87ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmann 88ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmann // See ModelAssociator interface. 89ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmann virtual bool CryptoReadyIfNecessary(); 90ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmann 91ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmann protected: 92ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmann // Stores the id of the node with the given tag in |sync_id|. 93ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmann // Returns of that node was found successfully. 94ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmann // Tests override this. 95ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmann virtual bool GetSyncIdForTaggedNode(const std::string& tag, int64* sync_id); 96ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmann 97ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmann private: 98ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmann typedef std::map<int64, int64> BookmarkIdToSyncIdMap; 99ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmann typedef std::map<int64, const BookmarkNode*> SyncIdToBookmarkNodeMap; 100ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmann typedef std::set<int64> DirtyAssociationsSyncIds; 101ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmann 102ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmann // Posts a task to persist dirty associations. 103ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmann void PostPersistAssociationsTask(); 104ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmann // Persists all dirty associations. 105ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmann void PersistAssociations(); 106ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmann 107ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmann // Loads the persisted associations into in-memory maps. 108ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmann // If the persisted associations are out-of-date due to some reason, returns 109ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmann // false; otherwise returns true. 110ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmann bool LoadAssociations(); 111ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmann 112ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmann // Matches up the bookmark model and the sync model to build model 113ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmann // associations. 114ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmann bool BuildAssociations(); 115ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmann 116ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmann // Associate a top-level node of the bookmark model with a permanent node in 117ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmann // the sync domain. Such permanent nodes are identified by a tag that is 118ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmann // well known to the server and the client, and is unique within a particular 119ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmann // user's share. For example, "other_bookmarks" is the tag for the Other 120ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmann // Bookmarks folder. The sync nodes are server-created. 121ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmann bool AssociateTaggedPermanentNode(const BookmarkNode* permanent_node, 122ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmann const std::string& tag); 123ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmann 124ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmann // Compare the properties of a pair of nodes from either domain. 125ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmann bool NodesMatch(const BookmarkNode* bookmark, 126ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmann const sync_api::BaseNode* sync_node) const; 127ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmann 128ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmann BookmarkModel* bookmark_model_; 129ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmann sync_api::UserShare* user_share_; 130ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmann UnrecoverableErrorHandler* unrecoverable_error_handler_; 131ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmann BookmarkIdToSyncIdMap id_map_; 132ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmann SyncIdToBookmarkNodeMap id_map_inverse_; 133ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmann // Stores sync ids for dirty associations. 134ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmann DirtyAssociationsSyncIds dirty_associations_sync_ids_; 135ec31984c45d9b3dd272ec3ecb9a5270a00494699Marcel Holtmann 136a6cb57cd010c728e97bb92f7ae6bbc12d61b66c8Siarhei Siamashka // Used to post PersistAssociation tasks to the current message loop and 137a6cb57cd010c728e97bb92f7ae6bbc12d61b66c8Siarhei Siamashka // guarantees no invocations can occur if |this| has been deleted. (This 138a6cb57cd010c728e97bb92f7ae6bbc12d61b66c8Siarhei Siamashka // allows this class to be non-refcounted). 139a6cb57cd010c728e97bb92f7ae6bbc12d61b66c8Siarhei Siamashka ScopedRunnableMethodFactory<BookmarkModelAssociator> persist_associations_; 140a6cb57cd010c728e97bb92f7ae6bbc12d61b66c8Siarhei Siamashka 141a6cb57cd010c728e97bb92f7ae6bbc12d61b66c8Siarhei Siamashka int number_of_new_sync_nodes_created_at_association_; 142a6cb57cd010c728e97bb92f7ae6bbc12d61b66c8Siarhei Siamashka 143a6cb57cd010c728e97bb92f7ae6bbc12d61b66c8Siarhei Siamashka DISALLOW_COPY_AND_ASSIGN(BookmarkModelAssociator); 144a6cb57cd010c728e97bb92f7ae6bbc12d61b66c8Siarhei Siamashka}; 145a6cb57cd010c728e97bb92f7ae6bbc12d61b66c8Siarhei Siamashka 146a6cb57cd010c728e97bb92f7ae6bbc12d61b66c8Siarhei Siamashka} // namespace browser_sync 147a6cb57cd010c728e97bb92f7ae6bbc12d61b66c8Siarhei Siamashka 148a6cb57cd010c728e97bb92f7ae6bbc12d61b66c8Siarhei Siamashka#endif // CHROME_BROWSER_SYNC_GLUE_BOOKMARK_MODEL_ASSOCIATOR_H_ 149a6cb57cd010c728e97bb92f7ae6bbc12d61b66c8Siarhei Siamashka