blob: 8eda3a1abe05baf7d0c6f276f55b5eaa2a72a9f5 [file] [log] [blame]
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef COMPONENTS_SYNC_BOOKMARKS_LOCAL_BOOKMARK_MODEL_MERGER_H_
#define COMPONENTS_SYNC_BOOKMARKS_LOCAL_BOOKMARK_MODEL_MERGER_H_
#include <unordered_map>
#include "base/memory/raw_ptr.h"
#include "base/uuid.h"
namespace bookmarks {
class BookmarkNode;
} // namespace bookmarks
namespace sync_bookmarks {
class BookmarkModelView;
// Class responsible for implementing the merge algorithm that allows moving all
// bookmarks from the local BookmarkModel instance to the account one.
class LocalBookmarkModelMerger {
public:
// All parameters must not be null and must outlive this object.
// The observer should itself take care.
LocalBookmarkModelMerger(const BookmarkModelView* local_model,
BookmarkModelView* account_model);
LocalBookmarkModelMerger(const LocalBookmarkModelMerger&) = delete;
LocalBookmarkModelMerger& operator=(const LocalBookmarkModelMerger&) = delete;
~LocalBookmarkModelMerger();
// Merges local bookmarks into the account model (both models injected in
// constructor).
void Merge();
private:
// Represents a pair of bookmarks, one in the source model and one in the
// destination one, that have been matched by UUID. They are guaranteed to
// have the same type and URL (if applicable).
struct GuidMatch {
raw_ptr<const bookmarks::BookmarkNode> local_node = nullptr;
raw_ptr<const bookmarks::BookmarkNode> account_node = nullptr;
};
// Computes bookmark pairs that should be matched by UUID. Note that matches
// may be incompatible, that is, if only one of the two is a folder.
static std::unordered_map<base::Uuid, GuidMatch, base::UuidHash>
FindGuidMatches(const BookmarkModelView* local_model,
const BookmarkModelView* account_model);
// Merges a local and a account subtrees. The input nodes are two equivalent
// local and remote nodes. This method tries to recursively match their
// children.
void MergeSubtree(const bookmarks::BookmarkNode* local_subtree_root,
const bookmarks::BookmarkNode* account_subtree_root);
// Updates `account_node` to hold the same semantics as `local_node`, which
// excludes the UUID (remains unchanged). `account_node` must not be a
// BookmarkPermanentNode.
void UpdateAccountNodeFromMatchingLocalNode(
const bookmarks::BookmarkNode* local_node,
const bookmarks::BookmarkNode* account_node);
// Copies a bookmark node from the local model to the account model. It works
// for both URL and folder nodes, but the latter case doesn't do anything
// about children (if any), the caller is responsible for copying over the
// children if desired.
const bookmarks::BookmarkNode* CopyLocalNodeToAccountModel(
const bookmarks::BookmarkNode* local_node,
const bookmarks::BookmarkNode* account_parent);
// If `account_node` has a local counterpart of the same UUID, returns the
// corresponding local node, otherwise returns a nullptr. `account_node` must
// not be null.
const bookmarks::BookmarkNode* FindMatchingLocalNodeByUuid(
const bookmarks::BookmarkNode* account_node) const;
// If `local_node` has an account counterpart of the same UUID, returns the
// corresponding account node, otherwise returns a nullptr.
const bookmarks::BookmarkNode* FindMatchingAccountNodeByUuid(
const bookmarks::BookmarkNode* local_node) const;
const raw_ptr<const BookmarkModelView> local_model_;
const raw_ptr<BookmarkModelView> account_model_;
const std::unordered_map<base::Uuid, GuidMatch, base::UuidHash>
uuid_to_match_map_;
};
} // namespace sync_bookmarks
#endif // COMPONENTS_SYNC_BOOKMARKS_LOCAL_BOOKMARK_MODEL_MERGER_H_