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