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

Side by Side Diff: chrome/browser/chromeos/gdata/gdata_files.cc

Issue 10258004: Parent/child fixes. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Created 8 years, 8 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
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/chromeos/gdata/gdata_files.h" 5 #include "chrome/browser/chromeos/gdata/gdata_files.h"
6 6
7 #include <vector> 7 #include <vector>
8 8
9 #include "base/utf_string_conversions.h" 9 #include "base/utf_string_conversions.h"
10 #include "base/platform_file.h" 10 #include "base/platform_file.h"
11 #include "base/stringprintf.h" 11 #include "base/stringprintf.h"
12 #include "base/string_util.h" 12 #include "base/string_util.h"
13 #include "chrome/browser/chromeos/gdata/find_entry_delegate.h" 13 #include "chrome/browser/chromeos/gdata/find_entry_delegate.h"
14 #include "chrome/browser/chromeos/gdata/gdata.pb.h" 14 #include "chrome/browser/chromeos/gdata/gdata.pb.h"
15 #include "chrome/browser/chromeos/gdata/gdata_parser.h" 15 #include "chrome/browser/chromeos/gdata/gdata_parser.h"
16 #include "net/base/escape.h" 16 #include "net/base/escape.h"
17 17
18 namespace gdata {
18 namespace { 19 namespace {
19 20
20 // Content refresh time. 21 // Content refresh time.
21 #ifndef NDEBUG 22 #ifndef NDEBUG
22 const int kRefreshTimeInSec = 10; 23 const int kRefreshTimeInSec = 10;
23 #else 24 #else
24 const int kRefreshTimeInSec = 5*60; 25 const int kRefreshTimeInSec = 5*60;
25 #endif 26 #endif
26 27
27 const char kSlash[] = "/"; 28 const char kSlash[] = "/";
28 const char kEscapedSlash[] = "\xE2\x88\x95"; 29 const char kEscapedSlash[] = "\xE2\x88\x95";
30 const FilePath::CharType kGDataRootDirectory[] = FILE_PATH_LITERAL("gdata");
29 31
30 std::string CacheSubDirectoryTypeToString( 32 std::string CacheSubDirectoryTypeToString(
31 gdata::GDataRootDirectory::CacheSubDirectoryType subdir) { 33 GDataRootDirectory::CacheSubDirectoryType subdir) {
32 switch (subdir) { 34 switch (subdir) {
33 case gdata::GDataRootDirectory::CACHE_TYPE_META: return "meta"; 35 case GDataRootDirectory::CACHE_TYPE_META: return "meta";
34 case gdata::GDataRootDirectory::CACHE_TYPE_PINNED: return "pinned"; 36 case GDataRootDirectory::CACHE_TYPE_PINNED: return "pinned";
35 case gdata::GDataRootDirectory::CACHE_TYPE_OUTGOING: return "outgoing"; 37 case GDataRootDirectory::CACHE_TYPE_OUTGOING: return "outgoing";
36 case gdata::GDataRootDirectory::CACHE_TYPE_PERSISTENT: return "persistent"; 38 case GDataRootDirectory::CACHE_TYPE_PERSISTENT: return "persistent";
37 case gdata::GDataRootDirectory::CACHE_TYPE_TMP: return "tmp"; 39 case GDataRootDirectory::CACHE_TYPE_TMP: return "tmp";
38 case gdata::GDataRootDirectory::CACHE_TYPE_TMP_DOWNLOADS: 40 case GDataRootDirectory::CACHE_TYPE_TMP_DOWNLOADS:
39 return "tmp_downloads"; 41 return "tmp_downloads";
40 case gdata::GDataRootDirectory::CACHE_TYPE_TMP_DOCUMENTS: 42 case GDataRootDirectory::CACHE_TYPE_TMP_DOCUMENTS:
41 return "tmp_documents"; 43 return "tmp_documents";
42 case gdata::GDataRootDirectory::NUM_CACHE_TYPES: 44 case GDataRootDirectory::NUM_CACHE_TYPES:
43 NOTREACHED(); 45 NOTREACHED();
44 } 46 }
45 NOTREACHED(); 47 NOTREACHED();
46 return "unknown subdir"; 48 return "unknown subdir";
47 } 49 }
48 50
49 // Extracts resource_id out of edit url. 51 // Extracts resource_id out of edit url.
50 std::string ExtractResourceId(const GURL& url) { 52 std::string ExtractResourceId(const GURL& url) {
51 return net::UnescapeURLComponent(url.ExtractFileName(), 53 return net::UnescapeURLComponent(url.ExtractFileName(),
52 net::UnescapeRule::URL_SPECIAL_CHARS); 54 net::UnescapeRule::URL_SPECIAL_CHARS);
53 } 55 }
54 56
55 } // namespace 57 } // namespace
56 58
57 namespace gdata {
58
59 // GDataEntry class. 59 // GDataEntry class.
60 60
61 GDataEntry::GDataEntry(GDataDirectory* parent, GDataRootDirectory* root) 61 GDataEntry::GDataEntry(GDataDirectory* parent, GDataRootDirectory* root)
62 : parent_(parent), 62 : root_(root),
63 root_(root),
64 deleted_(false) { 63 deleted_(false) {
64 SetParent(parent);
65 } 65 }
66 66
67 GDataEntry::~GDataEntry() { 67 GDataEntry::~GDataEntry() {
68 } 68 }
69 69
70 GDataFile* GDataEntry::AsGDataFile() { 70 GDataFile* GDataEntry::AsGDataFile() {
71 return NULL; 71 return NULL;
72 } 72 }
73 73
74 GDataDirectory* GDataEntry::AsGDataDirectory() { 74 GDataDirectory* GDataEntry::AsGDataDirectory() {
75 return NULL; 75 return NULL;
76 } 76 }
77 77
78 GDataRootDirectory* GDataEntry::AsGDataRootDirectory() { 78 GDataRootDirectory* GDataEntry::AsGDataRootDirectory() {
79 return NULL; 79 return NULL;
80 } 80 }
81 81
82 const GDataFile* GDataEntry::AsGDataFileConst() const { 82 const GDataFile* GDataEntry::AsGDataFileConst() const {
83 // cast away const and call the non-const version. This is safe. 83 // cast away const and call the non-const version. This is safe.
84 return const_cast<GDataEntry*>(this)->AsGDataFile(); 84 return const_cast<GDataEntry*>(this)->AsGDataFile();
85 } 85 }
86 86
87 const GDataDirectory* GDataEntry::AsGDataDirectoryConst() const { 87 const GDataDirectory* GDataEntry::AsGDataDirectoryConst() const {
88 // cast away const and call the non-const version. This is safe. 88 // cast away const and call the non-const version. This is safe.
89 return const_cast<GDataEntry*>(this)->AsGDataDirectory(); 89 return const_cast<GDataEntry*>(this)->AsGDataDirectory();
90 } 90 }
91 91
92 FilePath GDataEntry::GetFilePath() const { 92 FilePath GDataEntry::GetFilePath() const {
93 FilePath path; 93 FilePath path;
94 std::vector<FilePath::StringType> parts; 94 if (parent())
95 for (const GDataEntry* entry = this; entry != NULL; entry = entry->parent_) 95 path = parent()->GetFilePath();
96 parts.push_back(entry->file_name()); 96 path = path.Append(file_name());
97 return path;
98 }
97 99
98 // Paste paths parts back together in reverse order from upward tree 100 void GDataEntry::SetParent(GDataDirectory* parent) {
99 // traversal. 101 parent_ = parent;
100 for (std::vector<FilePath::StringType>::reverse_iterator iter = 102 parent_resource_id_ = parent ? parent->resource_id() : "";
satorux1 2012/04/27 21:35:41 IIRC, parent_resource_id_ was used for delta updat
achuithb 2012/04/27 22:15:03 I think it is. It should always point to the corre
101 parts.rbegin();
102 iter != parts.rend(); ++iter) {
103 path = path.Append(*iter);
104 }
105 return path;
106 } 103 }
107 104
108 void GDataEntry::SetFileNameFromTitle() { 105 void GDataEntry::SetFileNameFromTitle() {
109 file_name_ = EscapeUtf8FileName(title_); 106 file_name_ = EscapeUtf8FileName(title_);
110 } 107 }
111 108
112 // static. 109 // static.
113 GDataEntry* GDataEntry::FromDocumentEntry(GDataDirectory* parent, 110 GDataEntry* GDataEntry::FromDocumentEntry(GDataDirectory* parent,
114 DocumentEntry* doc, 111 DocumentEntry* doc,
115 GDataRootDirectory* root) { 112 GDataRootDirectory* root) {
116 DCHECK(doc); 113 DCHECK(doc);
117 if (doc->is_folder()) 114 if (doc->is_folder())
118 return GDataDirectory::FromDocumentEntry(parent, doc, root); 115 return GDataDirectory::FromDocumentEntry(parent, doc, root);
119 else if (doc->is_hosted_document() || doc->is_file()) 116 else if (doc->is_hosted_document() || doc->is_file())
120 return GDataFile::FromDocumentEntry(parent, doc, root); 117 return GDataFile::FromDocumentEntry(parent, doc, root);
121 118
122 return NULL; 119 return NULL;
123 } 120 }
124 121
125 // static. 122 // static.
126 std::string GDataEntry::EscapeUtf8FileName(const std::string& input) { 123 std::string GDataEntry::EscapeUtf8FileName(const std::string& input) {
127 std::string output; 124 std::string output;
128 if (ReplaceChars(input, kSlash, std::string(kEscapedSlash), &output)) 125 if (ReplaceChars(input, kSlash, std::string(kEscapedSlash), &output))
129 return output; 126 return output;
130 127
131 return input; 128 return input;
132 } 129 }
133 130
134 // static. 131 // static.
135 std::string GDataEntry::UnescapeUtf8FileName(const std::string& input) { 132 std::string GDataEntry::UnescapeUtf8FileName(const std::string& input) {
136 std::string output = input; 133 std::string output = input;
137 ReplaceSubstringsAfterOffset(&output, 0, std::string(kEscapedSlash), kSlash); 134 ReplaceSubstringsAfterOffset(&output, 0, std::string(kEscapedSlash), kSlash);
138 return output; 135 return output;
139 } 136 }
140 137
141 // GDataFile class implementation. 138 // GDataFile class implementation.
142 139
143 GDataFile::GDataFile(GDataDirectory* parent, GDataRootDirectory* root) 140 GDataFile::GDataFile(GDataDirectory* parent, GDataRootDirectory* root)
144 : GDataEntry(parent, root), 141 : GDataEntry(parent, root),
145 kind_(gdata::DocumentEntry::UNKNOWN), 142 kind_(DocumentEntry::UNKNOWN),
146 is_hosted_document_(false) { 143 is_hosted_document_(false) {
147 file_info_.is_directory = false; 144 file_info_.is_directory = false;
148 } 145 }
149 146
150 GDataFile::~GDataFile() { 147 GDataFile::~GDataFile() {
151 } 148 }
152 149
153 GDataFile* GDataFile::AsGDataFile() { 150 GDataFile* GDataFile::AsGDataFile() {
154 return this; 151 return this;
155 } 152 }
156 153
157 void GDataFile::SetFileNameFromTitle() { 154 void GDataFile::SetFileNameFromTitle() {
158 if (is_hosted_document_) { 155 if (is_hosted_document_) {
159 file_name_ = EscapeUtf8FileName(title_ + document_extension_); 156 file_name_ = EscapeUtf8FileName(title_ + document_extension_);
160 } else { 157 } else {
161 GDataEntry::SetFileNameFromTitle(); 158 GDataEntry::SetFileNameFromTitle();
162 } 159 }
163 } 160 }
164 161
165 // static. 162 // static.
166 GDataEntry* GDataFile::FromDocumentEntry(GDataDirectory* parent, 163 GDataEntry* GDataFile::FromDocumentEntry(GDataDirectory* parent,
167 DocumentEntry* doc, 164 DocumentEntry* doc,
168 GDataRootDirectory* root) { 165 GDataRootDirectory* root) {
169 DCHECK(doc->is_hosted_document() || doc->is_file()); 166 DCHECK(doc->is_hosted_document() || doc->is_file());
170 GDataFile* file = new GDataFile(parent, root); 167 GDataFile* file = new GDataFile(parent, root);
171 168
172 // For regular files, the 'filename' and 'title' attribute in the metadata 169 // For regular files, the 'filename' and 'title' attribute in the metadata
173 // may be different (e.g. due to rename). To be consistent with the web 170 // may be different (e.g. due to rename). To be consistent with the web
174 // interface and other client to use the 'title' attribute, instead of 171 // interface and other client to use the 'title' attribute, instead of
175 // 'filename', as the file name in the local snapshot. 172 // 'filename', as the file name in the local snapshot.
176 file->title_ = UTF16ToUTF8(doc->title()); 173 file->title_ = UTF16ToUTF8(doc->title());
177 174
178 // Check if this entry is a true file, or... 175 // Check if this entry is a true file, or...
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
234 GDataDirectory::~GDataDirectory() { 231 GDataDirectory::~GDataDirectory() {
235 RemoveChildren(); 232 RemoveChildren();
236 } 233 }
237 234
238 GDataDirectory* GDataDirectory::AsGDataDirectory() { 235 GDataDirectory* GDataDirectory::AsGDataDirectory() {
239 return this; 236 return this;
240 } 237 }
241 238
242 // static 239 // static
243 GDataEntry* GDataDirectory::FromDocumentEntry(GDataDirectory* parent, 240 GDataEntry* GDataDirectory::FromDocumentEntry(GDataDirectory* parent,
244 DocumentEntry* doc, 241 DocumentEntry* doc,
245 GDataRootDirectory* root) { 242 GDataRootDirectory* root) {
246 DCHECK(doc->is_folder()); 243 DCHECK(doc->is_folder());
247 GDataDirectory* dir = new GDataDirectory(parent, root); 244 GDataDirectory* dir = new GDataDirectory(parent, root);
248 dir->title_ = UTF16ToUTF8(doc->title()); 245 dir->title_ = UTF16ToUTF8(doc->title());
249 // SetFileNameFromTitle() must be called after |title_| is set. 246 // SetFileNameFromTitle() must be called after |title_| is set.
250 dir->SetFileNameFromTitle(); 247 dir->SetFileNameFromTitle();
251 dir->file_info_.last_modified = doc->updated_time(); 248 dir->file_info_.last_modified = doc->updated_time();
252 dir->file_info_.last_accessed = doc->updated_time(); 249 dir->file_info_.last_accessed = doc->updated_time();
253 dir->file_info_.creation_time = doc->published_time(); 250 dir->file_info_.creation_time = doc->published_time();
254 // Extract feed link. 251 // Extract feed link.
255 dir->start_feed_url_ = doc->content_url(); 252 dir->start_feed_url_ = doc->content_url();
(...skipping 10 matching lines...) Expand all
266 if (parent_link) 263 if (parent_link)
267 dir->parent_resource_id_ = ExtractResourceId(parent_link->href()); 264 dir->parent_resource_id_ = ExtractResourceId(parent_link->href());
268 265
269 const Link* upload_link = doc->GetLinkByType(Link::RESUMABLE_CREATE_MEDIA); 266 const Link* upload_link = doc->GetLinkByType(Link::RESUMABLE_CREATE_MEDIA);
270 if (upload_link) 267 if (upload_link)
271 dir->upload_url_ = upload_link->href(); 268 dir->upload_url_ = upload_link->href();
272 269
273 return dir; 270 return dir;
274 } 271 }
275 272
276 void GDataDirectory::RemoveChildren() {
277 // Remove children from resource map first.
278 root_->RemoveEntriesFromResourceMap(children_);
279
280 // Then delete and remove the children from tree.
281 STLDeleteValues(&children_);
282 children_.clear();
283 }
284
285 bool GDataDirectory::NeedsRefresh() const { 273 bool GDataDirectory::NeedsRefresh() const {
286 // Already refreshing by someone else. 274 // Already refreshing by someone else.
287 if (origin_ == REFRESHING) 275 if (origin_ == REFRESHING)
288 return false; 276 return false;
289 277
290 // Refresh is needed for content read from disk cache or stale content. 278 // Refresh is needed for content read from disk cache or stale content.
291 if (origin_ == FROM_CACHE) 279 if (origin_ == FROM_CACHE)
292 return true; 280 return true;
293 281
294 if ((base::Time::Now() - refresh_time_).InSeconds() < kRefreshTimeInSec) 282 if ((base::Time::Now() - refresh_time_).InSeconds() < kRefreshTimeInSec)
295 return false; 283 return false;
296 284
297 return true; 285 return true;
298 } 286 }
299 287
300 void GDataDirectory::AddEntry(GDataEntry* entry) { 288 void GDataDirectory::AddEntry(GDataEntry* entry) {
289 // The entry name may have been changed due to prior name de-duplication.
290 // We need to first restore the file name based on the title before going
291 // through name de-duplication again when it is added to another directory.
292 entry->SetFileNameFromTitle();
293
301 // Do file name de-duplication - find files with the same name and 294 // Do file name de-duplication - find files with the same name and
302 // append a name modifier to the name. 295 // append a name modifier to the name.
303 int max_modifier = 1; 296 int max_modifier = 1;
304 FilePath full_file_name(entry->file_name()); 297 FilePath full_file_name(entry->file_name());
305 std::string extension = full_file_name.Extension(); 298 const std::string extension = full_file_name.Extension();
306 std::string file_name = full_file_name.RemoveExtension().value(); 299 const std::string file_name = full_file_name.RemoveExtension().value();
307 while (children_.find(full_file_name.value()) != children_.end()) { 300 while (FindChild(full_file_name.value())) {
308 if (!extension.empty()) { 301 if (!extension.empty()) {
309 full_file_name = FilePath(base::StringPrintf("%s (%d)%s", 302 full_file_name = FilePath(base::StringPrintf("%s (%d)%s",
310 file_name.c_str(), 303 file_name.c_str(),
311 ++max_modifier, 304 ++max_modifier,
312 extension.c_str())); 305 extension.c_str()));
313 } else { 306 } else {
314 full_file_name = FilePath(base::StringPrintf("%s (%d)", 307 full_file_name = FilePath(base::StringPrintf("%s (%d)",
315 file_name.c_str(), 308 file_name.c_str(),
316 ++max_modifier)); 309 ++max_modifier));
317 } 310 }
318 } 311 }
319 if (full_file_name.value() != entry->file_name()) 312 entry->set_file_name(full_file_name.value());
320 entry->set_file_name(full_file_name.value()); 313
321 children_.insert(std::make_pair(entry->file_name(), entry)); 314 DVLOG(1) << "AddEntry: dir = " << GetFilePath().value()
322 DVLOG(1) << "Adding: " 315 << ", file = " + entry->file_name()
323 << this->GetFilePath().value() 316 << ", parent resource = " << entry->parent_resource_id()
324 << "/" + entry->file_name() 317 << ", resource = " + entry->resource_id();
325 << ", resource " << entry->parent_resource_id() 318
326 << "/" + entry->resource_id();
327 319
328 // Add entry to resource map. 320 // Add entry to resource map.
329 root_->AddEntryToResourceMap(entry); 321 root_->AddEntryToResourceMap(entry);
330 322 // Setup child and parent links.
331 entry->set_parent(this); 323 AddChild(entry);
324 entry->SetParent(this);
332 } 325 }
333 326
334 bool GDataDirectory::TakeEntry(GDataEntry* entry) { 327 bool GDataDirectory::TakeEntry(GDataEntry* entry) {
335 DCHECK(entry); 328 DCHECK(entry);
336 DCHECK(entry->parent()); 329 DCHECK(entry->parent());
337 330
338 entry->parent()->RemoveEntryFromChildrenList(entry); 331 entry->parent()->RemoveChild(entry);
339
340 // The entry name may have been changed due to prior name de-duplication.
341 // We need to first restore the file name based on the title before going
342 // through name de-duplication again when it is added to another directory.
343 entry->SetFileNameFromTitle();
344 AddEntry(entry); 332 AddEntry(entry);
345 333
346 return true; 334 return true;
347 } 335 }
348 336
349 bool GDataDirectory::TakeOverEntries(GDataDirectory* dir) { 337 bool GDataDirectory::TakeOverEntries(GDataDirectory* dir) {
350 for (GDataFileCollection::iterator iter = dir->children_.begin(); 338 for (GDataFileCollection::iterator iter = dir->child_files_.begin();
351 iter != dir->children_.end(); ++iter) { 339 iter != dir->child_files_.end(); ++iter) {
352 GDataEntry* entry = iter->second; 340 AddEntry(iter->second);
353 entry->SetFileNameFromTitle();
354 AddEntry(entry);
355 } 341 }
356 dir->children_.clear(); 342 dir->child_files_.clear();
343
344 for (GDataDirectoryCollection::iterator iter =
345 dir->child_directories_.begin();
346 iter != dir->child_directories_.end(); ++iter) {
347 AddEntry(iter->second);
348 }
349 dir->child_directories_.clear();
357 return true; 350 return true;
358 } 351 }
359 352
360 bool GDataDirectory::RemoveEntry(GDataEntry* entry) { 353 bool GDataDirectory::RemoveEntry(GDataEntry* entry) {
361 DCHECK(entry); 354 DCHECK(entry);
362 355
363 if (!RemoveEntryFromChildrenList(entry)) 356 if (!RemoveChild(entry))
364 return false; 357 return false;
365 358
366 delete entry; 359 delete entry;
367 return true; 360 return true;
368 } 361 }
369 362
370 bool GDataDirectory::RemoveEntryFromChildrenList(GDataEntry* entry) { 363 GDataEntry* GDataDirectory::FindChild(
364 const FilePath::StringType& file_name) const {
365 GDataFileCollection::const_iterator it = child_files_.find(file_name);
366 if (it != child_files_.end())
367 return it->second;
368
369 GDataDirectoryCollection::const_iterator itd =
370 child_directories_.find(file_name);
371 if (itd != child_directories_.end())
372 return itd->second;
373
374 return NULL;
375 }
376
377 void GDataDirectory::AddChild(GDataEntry* entry) {
371 DCHECK(entry); 378 DCHECK(entry);
372 379
373 GDataFileCollection::iterator iter = children_.find(entry->file_name()); 380 GDataFile* file = entry->AsGDataFile();
374 if (iter == children_.end()) 381 if (file)
382 child_files_.insert(std::make_pair(entry->file_name(), file));
383
384 GDataDirectory* directory = entry->AsGDataDirectory();
385 if (directory)
386 child_directories_.insert(std::make_pair(entry->file_name(), directory));
387 }
388
389 bool GDataDirectory::RemoveChild(GDataEntry* entry) {
390 DCHECK(entry);
391
392 const std::string file_name(entry->file_name());
393 GDataEntry* found_entry = FindChild(file_name);
394 if (!found_entry)
375 return false; 395 return false;
376 396
377 DCHECK(iter->second); 397 DCHECK_EQ(entry, found_entry);
378 DCHECK_EQ(entry, iter->second);
379 398
380 // Remove entry from resource map first. 399 // Remove entry from resource map first.
381 root_->RemoveEntryFromResourceMap(entry); 400 root_->RemoveEntryFromResourceMap(entry);
382 401
383 // Then delete it from tree. 402 // Then delete it from tree.
384 children_.erase(iter); 403 child_files_.erase(file_name);
404 child_directories_.erase(file_name);
385 405
386 return true; 406 return true;
387 } 407 }
388 408
409 void GDataDirectory::RemoveChildren() {
410 // Remove child files first.
411 for (GDataFileCollection::const_iterator iter = child_files_.begin();
412 iter != child_files_.end(); ++iter) {
413 root_->RemoveEntryFromResourceMap(iter->second);
414 }
415 STLDeleteValues(&child_files_);
416 child_files_.clear();
417
418 for (GDataDirectoryCollection::iterator iter = child_directories_.begin();
419 iter != child_directories_.end(); ++iter) {
420 GDataDirectory* dir = iter->second;
421 // Remove directories recursively.
422 dir->RemoveChildren();
423 root_->RemoveEntryFromResourceMap(dir);
424 }
425 STLDeleteValues(&child_directories_);
426 child_directories_.clear();
427 }
428
389 // GDataRootDirectory::CacheEntry struct implementation. 429 // GDataRootDirectory::CacheEntry struct implementation.
390 430
391 std::string GDataRootDirectory::CacheEntry::ToString() const { 431 std::string GDataRootDirectory::CacheEntry::ToString() const {
392 std::vector<std::string> cache_states; 432 std::vector<std::string> cache_states;
393 if (GDataFile::IsCachePresent(cache_state)) 433 if (GDataFile::IsCachePresent(cache_state))
394 cache_states.push_back("present"); 434 cache_states.push_back("present");
395 if (GDataFile::IsCachePinned(cache_state)) 435 if (GDataFile::IsCachePinned(cache_state))
396 cache_states.push_back("pinned"); 436 cache_states.push_back("pinned");
397 if (GDataFile::IsCacheDirty(cache_state)) 437 if (GDataFile::IsCacheDirty(cache_state))
398 cache_states.push_back("dirty"); 438 cache_states.push_back("dirty");
399 439
400 return base::StringPrintf("md5=%s, subdir=%s, cache_state=%s", 440 return base::StringPrintf("md5=%s, subdir=%s, cache_state=%s",
401 md5.c_str(), 441 md5.c_str(),
402 CacheSubDirectoryTypeToString(sub_dir_type).c_str(), 442 CacheSubDirectoryTypeToString(sub_dir_type).c_str(),
403 JoinString(cache_states, ',').c_str()); 443 JoinString(cache_states, ',').c_str());
404 } 444 }
405 445
406 // GDataRootDirectory class implementation. 446 // GDataRootDirectory class implementation.
407 447
408 GDataRootDirectory::GDataRootDirectory() 448 GDataRootDirectory::GDataRootDirectory()
409 : ALLOW_THIS_IN_INITIALIZER_LIST(GDataDirectory(NULL, this)), 449 : ALLOW_THIS_IN_INITIALIZER_LIST(GDataDirectory(NULL, this)),
410 largest_changestamp_(0), serialized_size_(0) { 450 largest_changestamp_(0), serialized_size_(0) {
451 title_ = kGDataRootDirectory;
452 SetFileNameFromTitle();
411 } 453 }
412 454
413 GDataRootDirectory::~GDataRootDirectory() { 455 GDataRootDirectory::~GDataRootDirectory() {
414 STLDeleteValues(&cache_map_); 456 STLDeleteValues(&cache_map_);
415 cache_map_.clear(); 457 cache_map_.clear();
416 458
417 resource_map_.clear(); 459 resource_map_.clear();
418 } 460 }
419 461
420 GDataRootDirectory* GDataRootDirectory::AsGDataRootDirectory() { 462 GDataRootDirectory* GDataRootDirectory::AsGDataRootDirectory() {
421 return this; 463 return this;
422 } 464 }
423 465
424 void GDataRootDirectory::AddEntryToResourceMap(GDataEntry* entry) { 466 void GDataRootDirectory::AddEntryToResourceMap(GDataEntry* entry) {
425 // GDataFileSystem has already locked. 467 // GDataFileSystem has already locked.
468 DVLOG(1) << "AddEntryToResourceMap " << entry->resource_id();
426 resource_map_.insert(std::make_pair(entry->resource_id(), entry)); 469 resource_map_.insert(std::make_pair(entry->resource_id(), entry));
427 } 470 }
428 471
429 void GDataRootDirectory::RemoveEntryFromResourceMap(GDataEntry* entry) { 472 void GDataRootDirectory::RemoveEntryFromResourceMap(GDataEntry* entry) {
430 // GDataFileSystem has already locked. 473 // GDataFileSystem has already locked.
431 resource_map_.erase(entry->resource_id()); 474 resource_map_.erase(entry->resource_id());
432 } 475 }
433 476
434 void GDataRootDirectory::RemoveEntriesFromResourceMap(
435 const GDataFileCollection& children) {
436 // GDataFileSystem has already locked.
437 for (GDataFileCollection::const_iterator iter = children.begin();
438 iter != children.end(); ++iter) {
439 // Recursively call RemoveEntrysFromResourceMap for each directory.
440 if (iter->second->AsGDataDirectory()) {
441 RemoveEntriesFromResourceMap(
442 iter->second->AsGDataDirectory()->children());
443 continue;
444 }
445
446 resource_map_.erase(iter->second->resource_id());
447 }
448 }
449
450 void GDataRootDirectory::FindEntryByPath( 477 void GDataRootDirectory::FindEntryByPath(
451 const FilePath& file_path, 478 const FilePath& file_path,
452 FindEntryDelegate* delegate) { 479 FindEntryDelegate* delegate) {
453 // GDataFileSystem has already locked. 480 // GDataFileSystem has already locked.
454 DCHECK(delegate); 481 DCHECK(delegate);
455 482
456 std::vector<FilePath::StringType> components; 483 std::vector<FilePath::StringType> components;
457 file_path.GetComponents(&components); 484 file_path.GetComponents(&components);
458 485
459 GDataDirectory* current_dir = this; 486 GDataDirectory* current_dir = this;
460 FilePath directory_path; 487 FilePath directory_path;
461 for (size_t i = 0; i < components.size() && current_dir; i++) { 488 for (size_t i = 0; i < components.size() && current_dir; i++) {
462 directory_path = directory_path.Append(current_dir->file_name()); 489 directory_path = directory_path.Append(current_dir->file_name());
463 490
464 // Last element must match, if not last then it must be a directory. 491 // Last element must match, if not last then it must be a directory.
465 if (i == components.size() - 1) { 492 if (i == components.size() - 1) {
466 if (current_dir->file_name() == components[i]) 493 if (current_dir->file_name() == components[i])
467 delegate->OnDone(base::PLATFORM_FILE_OK, directory_path, current_dir); 494 delegate->OnDone(base::PLATFORM_FILE_OK, directory_path, current_dir);
468 else 495 else
469 delegate->OnDone(base::PLATFORM_FILE_ERROR_NOT_FOUND, FilePath(), NULL); 496 delegate->OnDone(base::PLATFORM_FILE_ERROR_NOT_FOUND, FilePath(), NULL);
470 497
471 return; 498 return;
472 } 499 }
473 500
474 // Not the last part of the path, search for the next segment. 501 // Not the last part of the path, search for the next segment.
475 GDataFileCollection::const_iterator file_iter = 502 GDataEntry* entry = current_dir->FindChild(components[i + 1]);
476 current_dir->children().find(components[i + 1]); 503 if (!entry) {
477 if (file_iter == current_dir->children().end()) {
478 delegate->OnDone(base::PLATFORM_FILE_ERROR_NOT_FOUND, FilePath(), NULL); 504 delegate->OnDone(base::PLATFORM_FILE_ERROR_NOT_FOUND, FilePath(), NULL);
479 return; 505 return;
480 } 506 }
481 507
482 // Found file, must be the last segment. 508 // Found file, must be the last segment.
483 if (file_iter->second->file_info().is_directory) { 509 if (entry->file_info().is_directory) {
484 // Found directory, continue traversal. 510 // Found directory, continue traversal.
485 current_dir = file_iter->second->AsGDataDirectory(); 511 current_dir = entry->AsGDataDirectory();
486 } else { 512 } else {
487 if ((i + 1) == (components.size() - 1)) { 513 if ((i + 1) == (components.size() - 1)) {
488 delegate->OnDone(base::PLATFORM_FILE_OK, 514 delegate->OnDone(base::PLATFORM_FILE_OK,
489 directory_path, 515 directory_path,
490 file_iter->second); 516 entry);
491 } else { 517 } else {
492 delegate->OnDone(base::PLATFORM_FILE_ERROR_NOT_FOUND, FilePath(), NULL); 518 delegate->OnDone(base::PLATFORM_FILE_ERROR_NOT_FOUND, FilePath(), NULL);
493 } 519 }
494 520
495 return; 521 return;
496 } 522 }
497 } 523 }
498 delegate->OnDone(base::PLATFORM_FILE_ERROR_NOT_FOUND, FilePath(), NULL); 524 delegate->OnDone(base::PLATFORM_FILE_ERROR_NOT_FOUND, FilePath(), NULL);
499 } 525 }
500 526
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
610 file_info_.size = proto.file_info().size(); 636 file_info_.size = proto.file_info().size();
611 file_info_.is_directory = proto.file_info().is_directory(); 637 file_info_.is_directory = proto.file_info().is_directory();
612 file_info_.is_symbolic_link = proto.file_info().is_symbolic_link(); 638 file_info_.is_symbolic_link = proto.file_info().is_symbolic_link();
613 file_info_.last_modified = base::Time::FromInternalValue( 639 file_info_.last_modified = base::Time::FromInternalValue(
614 proto.file_info().last_modified()); 640 proto.file_info().last_modified());
615 file_info_.last_accessed = base::Time::FromInternalValue( 641 file_info_.last_accessed = base::Time::FromInternalValue(
616 proto.file_info().last_accessed()); 642 proto.file_info().last_accessed());
617 file_info_.creation_time = base::Time::FromInternalValue( 643 file_info_.creation_time = base::Time::FromInternalValue(
618 proto.file_info().creation_time()); 644 proto.file_info().creation_time());
619 645
620 file_name_ = proto.file_name();
621 title_ = proto.title(); 646 title_ = proto.title();
622 resource_id_ = proto.resource_id(); 647 resource_id_ = proto.resource_id();
648 parent_resource_id_ = proto.parent_resource_id();
623 edit_url_ = GURL(proto.edit_url()); 649 edit_url_ = GURL(proto.edit_url());
624 content_url_ = GURL(proto.content_url()); 650 content_url_ = GURL(proto.content_url());
651 SetFileNameFromTitle();
625 } 652 }
626 653
627 void GDataEntry::ToProto(GDataEntryProto* proto) const { 654 void GDataEntry::ToProto(GDataEntryProto* proto) const {
628 PlatformFileInfoProto* proto_file_info = proto->mutable_file_info(); 655 PlatformFileInfoProto* proto_file_info = proto->mutable_file_info();
629 proto_file_info->set_size(file_info_.size); 656 proto_file_info->set_size(file_info_.size);
630 proto_file_info->set_is_directory(file_info_.is_directory); 657 proto_file_info->set_is_directory(file_info_.is_directory);
631 proto_file_info->set_is_symbolic_link(file_info_.is_symbolic_link); 658 proto_file_info->set_is_symbolic_link(file_info_.is_symbolic_link);
632 proto_file_info->set_last_modified( 659 proto_file_info->set_last_modified(
633 file_info_.last_modified.ToInternalValue()); 660 file_info_.last_modified.ToInternalValue());
634 proto_file_info->set_last_accessed( 661 proto_file_info->set_last_accessed(
635 file_info_.last_accessed.ToInternalValue()); 662 file_info_.last_accessed.ToInternalValue());
636 proto_file_info->set_creation_time( 663 proto_file_info->set_creation_time(
637 file_info_.creation_time.ToInternalValue()); 664 file_info_.creation_time.ToInternalValue());
638 665
639 proto->set_file_name(file_name_);
640 proto->set_title(title_); 666 proto->set_title(title_);
641 proto->set_resource_id(resource_id_); 667 proto->set_resource_id(resource_id_);
668 proto->set_parent_resource_id(parent_resource_id_);
642 proto->set_edit_url(edit_url_.spec()); 669 proto->set_edit_url(edit_url_.spec());
643 proto->set_content_url(content_url_.spec()); 670 proto->set_content_url(content_url_.spec());
644 } 671 }
645 672
646 void GDataFile::FromProto(const GDataFileProto& proto) { 673 void GDataFile::FromProto(const GDataFileProto& proto) {
647 DCHECK(!proto.gdata_entry().file_info().is_directory()); 674 DCHECK(!proto.gdata_entry().file_info().is_directory());
648 GDataEntry::FromProto(proto.gdata_entry()); 675 GDataEntry::FromProto(proto.gdata_entry());
649 kind_ = DocumentEntry::EntryKind(proto.kind()); 676 kind_ = DocumentEntry::EntryKind(proto.kind());
650 thumbnail_url_ = GURL(proto.thumbnail_url()); 677 thumbnail_url_ = GURL(proto.thumbnail_url());
651 alternate_url_ = GURL(proto.alternate_url()); 678 alternate_url_ = GURL(proto.alternate_url());
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
692 } 719 }
693 720
694 void GDataDirectory::ToProto(GDataDirectoryProto* proto) const { 721 void GDataDirectory::ToProto(GDataDirectoryProto* proto) const {
695 GDataEntry::ToProto(proto->mutable_gdata_entry()); 722 GDataEntry::ToProto(proto->mutable_gdata_entry());
696 DCHECK(proto->gdata_entry().file_info().is_directory()); 723 DCHECK(proto->gdata_entry().file_info().is_directory());
697 proto->set_refresh_time(refresh_time_.ToInternalValue()); 724 proto->set_refresh_time(refresh_time_.ToInternalValue());
698 proto->set_start_feed_url(start_feed_url_.spec()); 725 proto->set_start_feed_url(start_feed_url_.spec());
699 proto->set_next_feed_url(next_feed_url_.spec()); 726 proto->set_next_feed_url(next_feed_url_.spec());
700 proto->set_upload_url(upload_url_.spec()); 727 proto->set_upload_url(upload_url_.spec());
701 proto->set_origin(origin_); 728 proto->set_origin(origin_);
702 for (GDataFileCollection::const_iterator iter = children_.begin(); 729 for (GDataFileCollection::const_iterator iter = child_files_.begin();
703 iter != children_.end(); ++iter) { 730 iter != child_files_.end(); ++iter) {
704 GDataFile* file = iter->second->AsGDataFile(); 731 GDataFile* file = iter->second;
705 GDataDirectory* dir = iter->second->AsGDataDirectory(); 732 file->ToProto(proto->add_child_files());
706 if (file) 733 }
707 file->ToProto(proto->add_child_files()); 734 for (GDataDirectoryCollection::const_iterator iter =
708 if (dir) 735 child_directories_.begin();
709 dir->ToProto(proto->add_child_directories()); 736 iter != child_directories_.end(); ++iter) {
737 GDataDirectory* dir = iter->second;
738 dir->ToProto(proto->add_child_directories());
710 } 739 }
711 } 740 }
712 741
713 void GDataRootDirectory::FromProto(const GDataRootDirectoryProto& proto) { 742 void GDataRootDirectory::FromProto(const GDataRootDirectoryProto& proto) {
714 root_ = this; 743 root_ = this;
715 GDataDirectory::FromProto(proto.gdata_directory()); 744 GDataDirectory::FromProto(proto.gdata_directory());
716 largest_changestamp_ = proto.largest_changestamp(); 745 largest_changestamp_ = proto.largest_changestamp();
717 } 746 }
718 747
719 void GDataRootDirectory::ToProto(GDataRootDirectoryProto* proto) const { 748 void GDataRootDirectory::ToProto(GDataRootDirectoryProto* proto) const {
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
778 bool ok = proto->ParseFromString(serialized_proto); 807 bool ok = proto->ParseFromString(serialized_proto);
779 if (ok) { 808 if (ok) {
780 FromProto(*proto.get()); 809 FromProto(*proto.get());
781 set_origin(FROM_CACHE); 810 set_origin(FROM_CACHE);
782 set_refresh_time(base::Time::Now()); 811 set_refresh_time(base::Time::Now());
783 } 812 }
784 return ok; 813 return ok;
785 } 814 }
786 815
787 } // namespace gdata 816 } // namespace gdata
OLDNEW
« chrome/browser/chromeos/gdata/gdata_files.h ('K') | « chrome/browser/chromeos/gdata/gdata_files.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698