summaryrefslogtreecommitdiffstats
path: root/chrome/browser/sync/glue/bookmark_model_associator.h
blob: e4bf930b8fbade7a4c1de1cf80039d61a92be338 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CHROME_BROWSER_SYNC_GLUE_BOOKMARK_MODEL_ASSOCIATOR_H_
#define CHROME_BROWSER_SYNC_GLUE_BOOKMARK_MODEL_ASSOCIATOR_H_

#include <map>
#include <set>
#include <string>

#include "base/basictypes.h"
#include "base/task.h"
#include "chrome/browser/sync/glue/model_associator.h"

class BookmarkNode;

namespace sync_api {
class BaseNode;
class BaseTransaction;
class ReadNode;
}

class ProfileSyncService;

namespace browser_sync {

class BookmarkChangeProcessor;
class UnrecoverableErrorHandler;

// Contains all model association related logic:
// * Algorithm to associate bookmark model and sync model.
// * Methods to get a bookmark node for a given sync node and vice versa.
// * Persisting model associations and loading them back.
class BookmarkModelAssociator
    : public PerDataTypeAssociatorInterface<BookmarkNode, int64> {
 public:
  static syncable::ModelType model_type() { return syncable::BOOKMARKS; }
  BookmarkModelAssociator(ProfileSyncService* sync_service,
                          UnrecoverableErrorHandler* error_handler);
  virtual ~BookmarkModelAssociator();

  // AssociatorInterface implementation.
  //
  // AssociateModels iterates through both the sync and the browser
  // bookmark model, looking for matched pairs of items.  For any pairs it
  // finds, it will call AssociateSyncID.  For any unmatched items,
  // MergeAndAssociateModels will try to repair the match, e.g. by adding a new
  // node.  After successful completion, the models should be identical and
  // corresponding. Returns true on success.  On failure of this step, we
  // should abort the sync operation and report an error to the user.
  virtual bool AssociateModels();

  virtual bool DisassociateModels();

  // The has_nodes out param is true if the sync model has nodes other
  // than the permanent tagged nodes.
  virtual bool SyncModelHasUserCreatedNodes(bool* has_nodes);

  // The has_nodes out param is true if the bookmark model has user
  // created nodes or not. That is, whether there are nodes in the
  // bookmark model except the bookmark bar and other bookmarks.
  virtual bool ChromeModelHasUserCreatedNodes(bool* has_nodes);

  // Returns sync id for the given bookmark node id.
  // Returns sync_api::kInvalidId if the sync node is not found for the given
  // bookmark node id.
  virtual int64 GetSyncIdFromChromeId(int64 node_id);

  // Returns the bookmark node for the given sync id.
  // Returns NULL if no bookmark node is found for the given sync id.
  virtual const BookmarkNode* GetChromeNodeFromSyncId(int64 sync_id);

  // Initializes the given sync node from the given bookmark node id.
  // Returns false if no sync node was found for the given bookmark node id or
  // if the initialization of sync node fails.
  virtual bool InitSyncNodeFromChromeId(int64 node_id,
                                        sync_api::BaseNode* sync_node);

  // Associates the given bookmark node with the given sync id.
  virtual void Associate(const BookmarkNode* node, int64 sync_id);
  // Remove the association that corresponds to the given sync id.
  virtual void Disassociate(int64 sync_id);

  virtual void AbortAssociation() {
    // No implementation needed, this associator runs on the main
    // thread.
  }

 protected:
  // Stores the id of the node with the given tag in |sync_id|.
  // Returns of that node was found successfully.
  // Tests override this.
  virtual bool GetSyncIdForTaggedNode(const std::string& tag, int64* sync_id);

  // Returns sync service instance.
  ProfileSyncService* sync_service() { return sync_service_; }

 private:
  typedef std::map<int64, int64> BookmarkIdToSyncIdMap;
  typedef std::map<int64, const BookmarkNode*> SyncIdToBookmarkNodeMap;
  typedef std::set<int64> DirtyAssociationsSyncIds;

  // Posts a task to persist dirty associations.
  void PostPersistAssociationsTask();
  // Persists all dirty associations.
  void PersistAssociations();

  // Loads the persisted associations into in-memory maps.
  // If the persisted associations are out-of-date due to some reason, returns
  // false; otherwise returns true.
  bool LoadAssociations();

  // Matches up the bookmark model and the sync model to build model
  // associations.
  bool BuildAssociations();

  // Associate a top-level node of the bookmark model with a permanent node in
  // the sync domain.  Such permanent nodes are identified by a tag that is
  // well known to the server and the client, and is unique within a particular
  // user's share.  For example, "other_bookmarks" is the tag for the Other
  // Bookmarks folder.  The sync nodes are server-created.
  bool AssociateTaggedPermanentNode(const BookmarkNode* permanent_node,
                                    const std::string& tag);

  // Compare the properties of a pair of nodes from either domain.
  bool NodesMatch(const BookmarkNode* bookmark,
                  const sync_api::BaseNode* sync_node) const;

  ProfileSyncService* sync_service_;
  UnrecoverableErrorHandler* error_handler_;
  BookmarkIdToSyncIdMap id_map_;
  SyncIdToBookmarkNodeMap id_map_inverse_;
  // Stores sync ids for dirty associations.
  DirtyAssociationsSyncIds dirty_associations_sync_ids_;

  // Used to post PersistAssociation tasks to the current message loop and
  // guarantees no invocations can occur if |this| has been deleted. (This
  // allows this class to be non-refcounted).
  ScopedRunnableMethodFactory<BookmarkModelAssociator> persist_associations_;

  DISALLOW_COPY_AND_ASSIGN(BookmarkModelAssociator);
};

}  // namespace browser_sync

#endif  // CHROME_BROWSER_SYNC_GLUE_BOOKMARK_MODEL_ASSOCIATOR_H_