1// Copyright 2014 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 COMPONENTS_ENHANCED_BOOKMARKS_ENHANCED_BOOKMARK_MODEL_H_
6#define COMPONENTS_ENHANCED_BOOKMARKS_ENHANCED_BOOKMARK_MODEL_H_
7
8#include <map>
9#include <string>
10
11#include "base/memory/weak_ptr.h"
12#include "base/observer_list.h"
13#include "base/strings/string16.h"
14#include "components/bookmarks/browser/base_bookmark_model_observer.h"
15#include "components/bookmarks/browser/bookmark_node.h"
16#include "components/keyed_service/core/keyed_service.h"
17
18namespace base {
19class Time;
20}  // namespace base
21
22class BookmarkModel;
23class BookmarkNode;
24class GURL;
25
26FORWARD_DECLARE_TEST(EnhancedBookmarkModelTest, SetMultipleMetaInfo);
27
28namespace enhanced_bookmarks {
29
30class EnhancedBookmarkModelObserver;
31
32// Wrapper around BookmarkModel providing utility functions for enhanced
33// bookmarks.
34class EnhancedBookmarkModel : public KeyedService,
35                              public BaseBookmarkModelObserver {
36 public:
37  EnhancedBookmarkModel(BookmarkModel* bookmark_model,
38                        const std::string& version);
39  virtual ~EnhancedBookmarkModel();
40
41  virtual void Shutdown() OVERRIDE;
42
43  void AddObserver(EnhancedBookmarkModelObserver* observer);
44  void RemoveObserver(EnhancedBookmarkModelObserver* observer);
45
46  // Moves |node| to |new_parent| and inserts it at the given |index|.
47  void Move(const BookmarkNode* node,
48            const BookmarkNode* new_parent,
49            int index);
50
51  // Adds a new folder node at the specified position.
52  const BookmarkNode* AddFolder(const BookmarkNode* parent,
53                                int index,
54                                const base::string16& title);
55
56  // Adds a url at the specified position.
57  const BookmarkNode* AddURL(const BookmarkNode* parent,
58                             int index,
59                             const base::string16& title,
60                             const GURL& url,
61                             const base::Time& creation_time);
62
63  // Returns the remote id for a bookmark |node|.
64  std::string GetRemoteId(const BookmarkNode* node);
65
66  // Returns the bookmark node corresponding to the given |remote_id|, or NULL
67  // if there is no node with the id.
68  const BookmarkNode* BookmarkForRemoteId(const std::string& remote_id);
69
70  // Sets the description of a bookmark |node|.
71  void SetDescription(const BookmarkNode* node, const std::string& description);
72
73  // Returns the description of a bookmark |node|.
74  std::string GetDescription(const BookmarkNode* node);
75
76  // Sets the URL of an image representative of a bookmark |node|.
77  // Expects the URL to be valid and not empty.
78  // Returns true if the metainfo is successfully populated.
79  bool SetOriginalImage(const BookmarkNode* node,
80                        const GURL& url,
81                        int width,
82                        int height);
83
84  // Returns the url and dimensions of the original scraped image of a
85  // bookmark |node|.
86  // Returns true if the out variables are populated, false otherwise.
87  bool GetOriginalImage(const BookmarkNode* node,
88                        GURL* url,
89                        int* width,
90                        int* height);
91
92  // Returns the url and dimensions of the server provided thumbnail image for
93  // a given bookmark |node|.
94  // Returns true if the out variables are populated, false otherwise.
95  bool GetThumbnailImage(const BookmarkNode* node,
96                         GURL* url,
97                         int* width,
98                         int* height);
99
100  // Returns a brief server provided synopsis of the bookmarked page.
101  // Returns the empty string if the snippet could not be extracted.
102  std::string GetSnippet(const BookmarkNode* node);
103
104  // Sets a custom suffix to be added to the version field when writing meta
105  // info fields.
106  void SetVersionSuffix(const std::string& version_suffix);
107
108  // TODO(rfevang): Add method + enum for accessing/writing flags.
109
110  // Used for testing, simulates the process that creates the thumbnails. Will
111  // remove existing entries for empty urls or set them if the url is not empty.
112  // Expects valid or empty urls. Returns true if the metainfo is successfully
113  // populated.
114  // TODO(rfevang): Move this to a testing only utility file.
115  bool SetAllImages(const BookmarkNode* node,
116                    const GURL& image_url,
117                    int image_width,
118                    int image_height,
119                    const GURL& thumbnail_url,
120                    int thumbnail_width,
121                    int thumbnail_height);
122
123  // TODO(rfevang): Ideally nothing should need the underlying bookmark model.
124  // Remove when that is actually the case.
125  BookmarkModel* bookmark_model() { return bookmark_model_; }
126
127  // Returns true if the enhanced bookmark model is done loading.
128  bool loaded() { return loaded_; }
129
130 private:
131  FRIEND_TEST_ALL_PREFIXES(::EnhancedBookmarkModelTest, SetMultipleMetaInfo);
132
133  typedef std::map<std::string, const BookmarkNode*> IdToNodeMap;
134  typedef std::map<const BookmarkNode*, std::string> NodeToIdMap;
135
136  // BaseBookmarkModelObserver:
137  virtual void BookmarkModelChanged() OVERRIDE;
138  virtual void BookmarkModelLoaded(BookmarkModel* model,
139                                   bool ids_reassigned) OVERRIDE;
140  virtual void BookmarkNodeAdded(BookmarkModel* model,
141                                 const BookmarkNode* parent,
142                                 int index) OVERRIDE;
143  virtual void BookmarkNodeRemoved(BookmarkModel* model,
144                                   const BookmarkNode* parent,
145                                   int old_index,
146                                   const BookmarkNode* node,
147                                   const std::set<GURL>& removed_urls) OVERRIDE;
148  virtual void OnWillChangeBookmarkMetaInfo(BookmarkModel* model,
149                                            const BookmarkNode* node) OVERRIDE;
150  virtual void BookmarkMetaInfoChanged(BookmarkModel* model,
151                                       const BookmarkNode* node) OVERRIDE;
152  virtual void BookmarkAllUserNodesRemoved(
153      BookmarkModel* model,
154      const std::set<GURL>& removed_urls) OVERRIDE;
155
156  // Initialize the mapping from remote ids to nodes.
157  void InitializeIdMap();
158
159  // Adds a node to the id map if it has a (unique) remote id. Must be followed
160  // by a (Schedule)ResetDuplicateRemoteIds call when done adding nodes.
161  void AddToIdMap(const BookmarkNode* node);
162
163  // If there are nodes that needs to reset their remote ids, schedules
164  // ResetDuplicateRemoteIds to be run asynchronously.
165  void ScheduleResetDuplicateRemoteIds();
166
167  // Clears out any duplicate remote ids detected by AddToIdMap calls.
168  void ResetDuplicateRemoteIds();
169
170  // Helper method for setting a meta info field on a node. Also updates the
171  // version field.
172  void SetMetaInfo(const BookmarkNode* node,
173                   const std::string& field,
174                   const std::string& value);
175
176  // Helper method for setting multiple meta info fields at once. All the fields
177  // in |meta_info| will be set, but the method will not delete fields not
178  // present.
179  void SetMultipleMetaInfo(const BookmarkNode* node,
180                           BookmarkNode::MetaInfoMap meta_info);
181
182  // Returns the version string to use when setting stars.version.
183  std::string GetVersionString();
184
185  BookmarkModel* bookmark_model_;
186  bool loaded_;
187
188  ObserverList<EnhancedBookmarkModelObserver> observers_;
189
190  base::WeakPtrFactory<EnhancedBookmarkModel> weak_ptr_factory_;
191
192  IdToNodeMap id_map_;
193  NodeToIdMap nodes_to_reset_;
194
195  // Caches the remote id of a node before its meta info changes.
196  std::string prev_remote_id_;
197
198  std::string version_;
199  std::string version_suffix_;
200};
201
202}  // namespace enhanced_bookmarks
203
204#endif  // COMPONENTS_ENHANCED_BOOKMARKS_ENHANCED_BOOKMARK_MODEL_H_
205