Home | History | Annotate | Download | only in glue
      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:
     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 
     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