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