Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(61)

Side by Side Diff: chrome/browser/bookmark_storage.cc

Issue 1868: Moves bookmark related classes into bookmarks directory. There are no... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Created 12 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « chrome/browser/bookmark_storage.h ('k') | chrome/browser/bookmarks/bookmark_bar_model.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2006-2008 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 #include "chrome/browser/bookmark_storage.h"
6
7 #include "base/file_util.h"
8 #include "base/json_writer.h"
9 #include "base/message_loop.h"
10 #include "chrome/browser/bookmark_bar_model.h"
11 #include "chrome/browser/bookmark_codec.h"
12 #include "chrome/browser/profile.h"
13 #include "chrome/common/chrome_constants.h"
14 #include "chrome/common/json_value_serializer.h"
15
16 namespace {
17
18 // Extension used for backup files (copy of main file created during startup).
19 const wchar_t* const kBackupExtension = L"bak";
20
21 // Extension for the temporary file. We write to the temp file than move to
22 // kBookmarksFileName.
23 const wchar_t* const kTmpExtension = L"tmp";
24
25 // How often we save.
26 const int kSaveDelayMS = 2500;
27
28 } // namespace
29
30 // BookmarkStorage -------------------------------------------------------------
31
32 BookmarkStorage::BookmarkStorage(Profile* profile, BookmarkBarModel* model)
33 : model_(model),
34 #pragma warning(suppress: 4355) // Okay to pass "this" here.
35 save_factory_(this),
36 backend_thread_(g_browser_process->file_thread()) {
37 std::wstring path = profile->GetPath();
38 file_util::AppendToPath(&path, chrome::kBookmarksFileName);
39 std::wstring tmp_history_path = profile->GetPath();
40 file_util::AppendToPath(&tmp_history_path, chrome::kHistoryBookmarksFileName);
41 backend_ = new BookmarkStorageBackend(path, tmp_history_path);
42 }
43
44 void BookmarkStorage::LoadBookmarks(bool load_from_history) {
45 if (!backend_thread()) {
46 backend_->Read(scoped_refptr<BookmarkStorage>(this), NULL,
47 load_from_history);
48 } else {
49 backend_thread()->message_loop()->PostTask(
50 FROM_HERE,
51 NewRunnableMethod(backend_.get(), &BookmarkStorageBackend::Read,
52 scoped_refptr<BookmarkStorage>(this),
53 MessageLoop::current(), load_from_history));
54 }
55 }
56
57 void BookmarkStorage::ScheduleSave() {
58 if (!backend_thread()) {
59 SaveNow();
60 } else if (save_factory_.empty()) {
61 MessageLoop::current()->PostDelayedTask(
62 FROM_HERE, save_factory_.NewRunnableMethod(&BookmarkStorage::SaveNow),
63 kSaveDelayMS);
64 }
65 }
66
67 void BookmarkStorage::BookmarkModelDeleted() {
68 if (!save_factory_.empty()) {
69 // There's a pending save. We need to save now as otherwise by the time
70 // SaveNow is invoked the model is gone.
71 save_factory_.RevokeAll();
72 SaveNow();
73 }
74 model_ = NULL;
75 }
76
77 void BookmarkStorage::LoadedBookmarks(Value* root_value,
78 bool bookmark_file_exists,
79 bool loaded_from_history) {
80 scoped_ptr<Value> value_ref(root_value);
81
82 if (model_) {
83 if (root_value) {
84 BookmarkCodec codec;
85 codec.Decode(model_, *root_value);
86 }
87 model_->OnBookmarkStorageLoadedBookmarks(bookmark_file_exists,
88 loaded_from_history);
89 }
90 }
91
92 void BookmarkStorage::SaveNow() {
93 if (!model_ || !model_->IsLoaded()) {
94 // We should only get here if we have a valid model and it's finished
95 // loading.
96 NOTREACHED();
97 return;
98 }
99
100 BookmarkCodec codec;
101 Value* value = codec.Encode(model_);
102 // The backend deletes value in write.
103 if (!backend_thread()) {
104 backend_->Write(value);
105 } else {
106 backend_thread()->message_loop()->PostTask(
107 FROM_HERE,
108 NewRunnableMethod(backend_.get(), &BookmarkStorageBackend::Write,
109 value));
110 }
111 }
112
113 // BookmarkStorageBackend ------------------------------------------------------
114
115 BookmarkStorageBackend::BookmarkStorageBackend(
116 const std::wstring& path,
117 const std::wstring& tmp_history_path)
118 : path_(path),
119 tmp_history_path_(tmp_history_path) {
120 // Make a backup of the current file.
121 std::wstring backup_path = path;
122 file_util::ReplaceExtension(&backup_path, kBackupExtension);
123 file_util::CopyFile(path, backup_path);
124 }
125
126 void BookmarkStorageBackend::Write(Value* value) {
127 DCHECK(value);
128
129 // We own Value.
130 scoped_ptr<Value> value_ref(value);
131
132 std::string content;
133 JSONWriter::Write(value, true, &content);
134
135 // Write to a temp file, then rename.
136 std::wstring tmp_file = path_;
137 file_util::ReplaceExtension(&tmp_file, kTmpExtension);
138
139 int bytes_written = file_util::WriteFile(tmp_file, content.c_str(),
140 static_cast<int>(content.length()));
141 if (bytes_written != -1) {
142 if (!MoveFileEx(tmp_file.c_str(), path_.c_str(),
143 MOVEFILE_COPY_ALLOWED | MOVEFILE_REPLACE_EXISTING)) {
144 // Rename failed. Try again on the off chance someone has locked either
145 // file and hope we're successful the second time through.
146 BOOL move_result =
147 MoveFileEx(tmp_file.c_str(), path_.c_str(),
148 MOVEFILE_COPY_ALLOWED | MOVEFILE_REPLACE_EXISTING);
149 DCHECK(move_result);
150 }
151 // Nuke the history file so that we don't attempt to load from it again.
152 file_util::Delete(tmp_history_path_, false);
153 }
154 }
155
156 void BookmarkStorageBackend::Read(scoped_refptr<BookmarkStorage> service,
157 MessageLoop* message_loop,
158 bool load_from_history) {
159 const std::wstring& path = load_from_history ? tmp_history_path_ : path_;
160 bool bookmark_file_exists = file_util::PathExists(path);
161 Value* root = NULL;
162 if (bookmark_file_exists) {
163 JSONFileValueSerializer serializer(path);
164 serializer.Deserialize(&root);
165 }
166
167 // BookmarkStorage takes ownership of root.
168 if (message_loop) {
169 message_loop->PostTask(FROM_HERE, NewRunnableMethod(
170 service.get(), &BookmarkStorage::LoadedBookmarks, root,
171 bookmark_file_exists, load_from_history));
172 } else {
173 service->LoadedBookmarks(root, bookmark_file_exists, load_from_history);
174 }
175 }
OLDNEW
« no previous file with comments | « chrome/browser/bookmark_storage.h ('k') | chrome/browser/bookmarks/bookmark_bar_model.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698