Home | History | Annotate | Download | only in glue
      1 // Copyright (c) 2012 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 
      8 #include <map>
      9 #include <set>
     10 #include <string>
     11 
     12 #include "base/basictypes.h"
     13 #include "base/compiler_specific.h"
     14 #include "base/memory/weak_ptr.h"
     15 #include "components/sync_driver/data_type_controller.h"
     16 #include "components/sync_driver/data_type_error_handler.h"
     17 #include "components/sync_driver/model_associator.h"
     18 #include "sync/internal_api/public/util/unrecoverable_error_handler.h"
     19 
     20 class BookmarkModel;
     21 class BookmarkNode;
     22 class Profile;
     23 
     24 namespace syncer {
     25 class BaseNode;
     26 class BaseTransaction;
     27 struct UserShare;
     28 }
     29 
     30 namespace browser_sync {
     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:
     39   static syncer::ModelType model_type() { return syncer::BOOKMARKS; }
     40   // |expect_mobile_bookmarks_folder| controls whether or not we
     41   // expect the mobile bookmarks permanent folder to be created.
     42   // Should be set to true only by mobile clients.
     43   BookmarkModelAssociator(
     44       BookmarkModel* bookmark_model,
     45       Profile* profile_,
     46       syncer::UserShare* user_share,
     47       DataTypeErrorHandler* unrecoverable_error_handler,
     48       bool expect_mobile_bookmarks_folder);
     49   virtual ~BookmarkModelAssociator();
     50 
     51   // Updates the visibility of the permanents node in the BookmarkModel.
     52   void UpdatePermanentNodeVisibility();
     53 
     54   // AssociatorInterface implementation.
     55   //
     56   // AssociateModels iterates through both the sync and the browser
     57   // bookmark model, looking for matched pairs of items.  For any pairs it
     58   // finds, it will call AssociateSyncID.  For any unmatched items,
     59   // MergeAndAssociateModels will try to repair the match, e.g. by adding a new
     60   // node.  After successful completion, the models should be identical and
     61   // corresponding. Returns true on success.  On failure of this step, we
     62   // should abort the sync operation and report an error to the user.
     63   virtual syncer::SyncError AssociateModels(
     64       syncer::SyncMergeResult* local_merge_result,
     65       syncer::SyncMergeResult* syncer_merge_result) OVERRIDE;
     66 
     67   virtual syncer::SyncError DisassociateModels() OVERRIDE;
     68 
     69   // The has_nodes out param is true if the sync model has nodes other
     70   // than the permanent tagged nodes.
     71   virtual bool SyncModelHasUserCreatedNodes(bool* has_nodes) OVERRIDE;
     72 
     73   // Returns sync id for the given bookmark node id.
     74   // Returns syncer::kInvalidId if the sync node is not found for the given
     75   // bookmark node id.
     76   virtual int64 GetSyncIdFromChromeId(const int64& node_id) OVERRIDE;
     77 
     78   // Returns the bookmark node for the given sync id.
     79   // Returns NULL if no bookmark node is found for the given sync id.
     80   virtual const BookmarkNode* GetChromeNodeFromSyncId(int64 sync_id) OVERRIDE;
     81 
     82   // Initializes the given sync node from the given bookmark node id.
     83   // Returns false if no sync node was found for the given bookmark node id or
     84   // if the initialization of sync node fails.
     85   virtual bool InitSyncNodeFromChromeId(
     86       const int64& node_id,
     87       syncer::BaseNode* sync_node) OVERRIDE;
     88 
     89   // Associates the given bookmark node with the given sync id.
     90   virtual void Associate(const BookmarkNode* node, int64 sync_id) OVERRIDE;
     91   // Remove the association that corresponds to the given sync id.
     92   virtual void Disassociate(int64 sync_id) OVERRIDE;
     93 
     94   virtual void AbortAssociation() OVERRIDE {
     95     // No implementation needed, this associator runs on the main
     96     // thread.
     97   }
     98 
     99   // See ModelAssociator interface.
    100   virtual bool CryptoReadyIfNecessary() OVERRIDE;
    101 
    102  protected:
    103   // Stores the id of the node with the given tag in |sync_id|.
    104   // Returns of that node was found successfully.
    105   // Tests override this.
    106   virtual bool GetSyncIdForTaggedNode(const std::string& tag, int64* sync_id);
    107 
    108  private:
    109   typedef std::map<int64, int64> BookmarkIdToSyncIdMap;
    110   typedef std::map<int64, const BookmarkNode*> SyncIdToBookmarkNodeMap;
    111   typedef std::set<int64> DirtyAssociationsSyncIds;
    112 
    113   // Posts a task to persist dirty associations.
    114   void PostPersistAssociationsTask();
    115   // Persists all dirty associations.
    116   void PersistAssociations();
    117 
    118   // Matches up the bookmark model and the sync model to build model
    119   // associations.
    120   syncer::SyncError BuildAssociations(
    121       syncer::SyncMergeResult* local_merge_result,
    122       syncer::SyncMergeResult* syncer_merge_result);
    123 
    124   // Removes bookmark nodes whose corresponding sync nodes have been deleted
    125   // according to sync delete journals. Return number of deleted bookmarks.
    126   int64 ApplyDeletesFromSyncJournal(syncer::BaseTransaction* trans);
    127 
    128   // Associate a top-level node of the bookmark model with a permanent node in
    129   // the sync domain.  Such permanent nodes are identified by a tag that is
    130   // well known to the server and the client, and is unique within a particular
    131   // user's share.  For example, "other_bookmarks" is the tag for the Other
    132   // Bookmarks folder.  The sync nodes are server-created.
    133   // Returns true on success, false if association failed.
    134   bool AssociateTaggedPermanentNode(
    135       const BookmarkNode* permanent_node,
    136       const std::string& tag) WARN_UNUSED_RESULT;
    137 
    138   // Compare the properties of a pair of nodes from either domain.
    139   bool NodesMatch(const BookmarkNode* bookmark,
    140                   const syncer::BaseNode* sync_node) const;
    141 
    142   // Check whether bookmark model and sync model are synced by comparing
    143   // their transaction versions.
    144   // Returns a PERSISTENCE_ERROR if a transaction mismatch was detected where
    145   // the native model has a newer transaction verison.
    146   syncer::SyncError CheckModelSyncState(
    147       syncer::SyncMergeResult* local_merge_result,
    148       syncer::SyncMergeResult* syncer_merge_result) const;
    149 
    150   BookmarkModel* bookmark_model_;
    151   Profile* profile_;
    152   syncer::UserShare* user_share_;
    153   DataTypeErrorHandler* unrecoverable_error_handler_;
    154   const bool expect_mobile_bookmarks_folder_;
    155   BookmarkIdToSyncIdMap id_map_;
    156   SyncIdToBookmarkNodeMap id_map_inverse_;
    157   // Stores sync ids for dirty associations.
    158   DirtyAssociationsSyncIds dirty_associations_sync_ids_;
    159 
    160   // Used to post PersistAssociation tasks to the current message loop and
    161   // guarantees no invocations can occur if |this| has been deleted. (This
    162   // allows this class to be non-refcounted).
    163   base::WeakPtrFactory<BookmarkModelAssociator> weak_factory_;
    164 
    165   DISALLOW_COPY_AND_ASSIGN(BookmarkModelAssociator);
    166 };
    167 
    168 }  // namespace browser_sync
    169 
    170 #endif  // CHROME_BROWSER_SYNC_GLUE_BOOKMARK_MODEL_ASSOCIATOR_H_
    171