OLD | NEW |
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 <leveldb/db.h> | 7 #include <leveldb/db.h> |
8 #include <vector> | |
9 | 8 |
10 #include "base/message_loop_proxy.h" | 9 #include "base/message_loop_proxy.h" |
11 #include "base/platform_file.h" | 10 #include "base/platform_file.h" |
12 #include "base/string_number_conversions.h" | 11 #include "base/string_number_conversions.h" |
13 #include "base/string_util.h" | 12 #include "base/string_util.h" |
14 #include "base/stringprintf.h" | 13 #include "base/stringprintf.h" |
15 #include "base/sequenced_task_runner.h" | 14 #include "base/sequenced_task_runner.h" |
16 #include "base/tracked_objects.h" | 15 #include "base/tracked_objects.h" |
17 #include "base/utf_string_conversions.h" | 16 #include "base/utf_string_conversions.h" |
18 #include "chrome/browser/chromeos/gdata/gdata.pb.h" | 17 #include "chrome/browser/chromeos/gdata/gdata.pb.h" |
(...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
247 | 246 |
248 void GDataDirectory::InitFromDocumentEntry(DocumentEntry* doc) { | 247 void GDataDirectory::InitFromDocumentEntry(DocumentEntry* doc) { |
249 GDataEntry::InitFromDocumentEntry(doc); | 248 GDataEntry::InitFromDocumentEntry(doc); |
250 | 249 |
251 const Link* upload_link = doc->GetLinkByType(Link::RESUMABLE_CREATE_MEDIA); | 250 const Link* upload_link = doc->GetLinkByType(Link::RESUMABLE_CREATE_MEDIA); |
252 if (upload_link) | 251 if (upload_link) |
253 upload_url_ = upload_link->href(); | 252 upload_url_ = upload_link->href(); |
254 } | 253 } |
255 | 254 |
256 void GDataDirectory::AddEntry(GDataEntry* entry) { | 255 void GDataDirectory::AddEntry(GDataEntry* entry) { |
| 256 DCHECK(!entry->parent()); |
| 257 |
257 // The entry name may have been changed due to prior name de-duplication. | 258 // The entry name may have been changed due to prior name de-duplication. |
258 // We need to first restore the file name based on the title before going | 259 // We need to first restore the file name based on the title before going |
259 // through name de-duplication again when it is added to another directory. | 260 // through name de-duplication again when it is added to another directory. |
260 entry->SetBaseNameFromTitle(); | 261 entry->SetBaseNameFromTitle(); |
261 | 262 |
262 // Do file name de-duplication - find files with the same name and | 263 // Do file name de-duplication - find files with the same name and |
263 // append a name modifier to the name. | 264 // append a name modifier to the name. |
264 int max_modifier = 1; | 265 int max_modifier = 1; |
265 FilePath full_file_name(entry->base_name()); | 266 FilePath full_file_name(entry->base_name()); |
266 const std::string extension = full_file_name.Extension(); | 267 const std::string extension = full_file_name.Extension(); |
(...skipping 22 matching lines...) Expand all Loading... |
289 directory_service_->AddEntryToResourceMap(entry); | 290 directory_service_->AddEntryToResourceMap(entry); |
290 | 291 |
291 // Setup child and parent links. | 292 // Setup child and parent links. |
292 AddChild(entry); | 293 AddChild(entry); |
293 entry->SetParent(this); | 294 entry->SetParent(this); |
294 } | 295 } |
295 | 296 |
296 bool GDataDirectory::TakeOverEntries(GDataDirectory* dir) { | 297 bool GDataDirectory::TakeOverEntries(GDataDirectory* dir) { |
297 for (GDataFileCollection::iterator iter = dir->child_files_.begin(); | 298 for (GDataFileCollection::iterator iter = dir->child_files_.begin(); |
298 iter != dir->child_files_.end(); ++iter) { | 299 iter != dir->child_files_.end(); ++iter) { |
299 AddEntry(iter->second); | 300 GDataEntry* entry = iter->second; |
| 301 entry->SetParent(NULL); |
| 302 AddEntry(entry); |
300 } | 303 } |
301 dir->child_files_.clear(); | 304 dir->child_files_.clear(); |
302 | 305 |
303 for (GDataDirectoryCollection::iterator iter = | 306 for (GDataDirectoryCollection::iterator iter = |
304 dir->child_directories_.begin(); | 307 dir->child_directories_.begin(); |
305 iter != dir->child_directories_.end(); ++iter) { | 308 iter != dir->child_directories_.end(); ++iter) { |
306 AddEntry(iter->second); | 309 GDataEntry* entry = iter->second; |
| 310 entry->SetParent(NULL); |
| 311 AddEntry(entry); |
307 } | 312 } |
308 dir->child_directories_.clear(); | 313 dir->child_directories_.clear(); |
309 return true; | 314 return true; |
310 } | 315 } |
311 | 316 |
312 void GDataDirectory::RemoveEntry(GDataEntry* entry) { | 317 void GDataDirectory::RemoveEntry(GDataEntry* entry) { |
313 DCHECK(entry); | 318 DCHECK(entry); |
314 | 319 |
315 RemoveChild(entry); | 320 RemoveChild(entry); |
316 delete entry; | 321 delete entry; |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
348 const std::string& base_name(entry->base_name()); | 353 const std::string& base_name(entry->base_name()); |
349 // entry must be present in this directory. | 354 // entry must be present in this directory. |
350 DCHECK_EQ(entry, FindChild(base_name)); | 355 DCHECK_EQ(entry, FindChild(base_name)); |
351 // Remove entry from resource map first. | 356 // Remove entry from resource map first. |
352 if (directory_service_) | 357 if (directory_service_) |
353 directory_service_->RemoveEntryFromResourceMap(entry); | 358 directory_service_->RemoveEntryFromResourceMap(entry); |
354 | 359 |
355 // Then delete it from tree. | 360 // Then delete it from tree. |
356 child_files_.erase(base_name); | 361 child_files_.erase(base_name); |
357 child_directories_.erase(base_name); | 362 child_directories_.erase(base_name); |
| 363 |
| 364 entry->SetParent(NULL); |
358 } | 365 } |
359 | 366 |
360 void GDataDirectory::RemoveChildren() { | 367 void GDataDirectory::RemoveChildren() { |
361 RemoveChildFiles(); | 368 RemoveChildFiles(); |
362 RemoveChildDirectories(); | 369 RemoveChildDirectories(); |
363 } | 370 } |
364 | 371 |
365 void GDataDirectory::RemoveChildFiles() { | 372 void GDataDirectory::RemoveChildFiles() { |
366 for (GDataFileCollection::const_iterator iter = child_files_.begin(); | 373 for (GDataFileCollection::const_iterator iter = child_files_.begin(); |
367 iter != child_files_.end(); ++iter) { | 374 iter != child_files_.end(); ++iter) { |
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
556 void GDataDirectoryService::ClearRoot() { | 563 void GDataDirectoryService::ClearRoot() { |
557 // Note that children have a reference to root_, | 564 // Note that children have a reference to root_, |
558 // so we need to delete them here. | 565 // so we need to delete them here. |
559 root_->RemoveChildren(); | 566 root_->RemoveChildren(); |
560 RemoveEntryFromResourceMap(root_.get()); | 567 RemoveEntryFromResourceMap(root_.get()); |
561 DCHECK(resource_map_.empty()); | 568 DCHECK(resource_map_.empty()); |
562 resource_map_.clear(); | 569 resource_map_.clear(); |
563 root_.reset(); | 570 root_.reset(); |
564 } | 571 } |
565 | 572 |
| 573 void GDataDirectoryService::AddEntryToDirectory( |
| 574 GDataDirectory* directory, |
| 575 GDataEntry* new_entry, |
| 576 const FileMoveCallback& callback) { |
| 577 DCHECK(directory); |
| 578 DCHECK(new_entry); |
| 579 DCHECK(!callback.is_null()); |
| 580 |
| 581 directory->AddEntry(new_entry); |
| 582 DVLOG(1) << "AddEntryToDirectory " << new_entry->GetFilePath().value(); |
| 583 base::MessageLoopProxy::current()->PostTask(FROM_HERE, |
| 584 base::Bind(callback, GDATA_FILE_OK, new_entry->GetFilePath())); |
| 585 } |
| 586 |
566 void GDataDirectoryService::MoveEntryToDirectory( | 587 void GDataDirectoryService::MoveEntryToDirectory( |
567 const FilePath& directory_path, | 588 const FilePath& directory_path, |
568 GDataEntry* entry, | 589 GDataEntry* entry, |
569 const FileMoveCallback& callback) { | 590 const FileMoveCallback& callback) { |
570 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 591 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
571 DCHECK(entry); | 592 DCHECK(entry); |
572 | 593 |
573 if (entry->parent()) | 594 if (entry->parent()) |
574 entry->parent()->RemoveChild(entry); | 595 entry->parent()->RemoveChild(entry); |
575 | 596 |
576 GDataEntry* destination = FindEntryByPathSync(directory_path); | 597 GDataEntry* destination = FindEntryByPathSync(directory_path); |
577 FilePath moved_file_path; | 598 FilePath moved_file_path; |
578 GDataFileError error = GDATA_FILE_ERROR_FAILED; | 599 GDataFileError error = GDATA_FILE_ERROR_FAILED; |
579 if (!destination) { | 600 if (!destination) { |
580 error = GDATA_FILE_ERROR_NOT_FOUND; | 601 error = GDATA_FILE_ERROR_NOT_FOUND; |
581 } else if (!destination->AsGDataDirectory()) { | 602 } else if (!destination->AsGDataDirectory()) { |
582 error = GDATA_FILE_ERROR_NOT_A_DIRECTORY; | 603 error = GDATA_FILE_ERROR_NOT_A_DIRECTORY; |
583 } else { | 604 } else { |
584 destination->AsGDataDirectory()->AddEntry(entry); | 605 destination->AsGDataDirectory()->AddEntry(entry); |
585 moved_file_path = entry->GetFilePath(); | 606 moved_file_path = entry->GetFilePath(); |
586 error = GDATA_FILE_OK; | 607 error = GDATA_FILE_OK; |
587 } | 608 } |
| 609 DVLOG(1) << "MoveEntryToDirectory " << moved_file_path.value(); |
588 if (!callback.is_null()) { | 610 if (!callback.is_null()) { |
589 base::MessageLoopProxy::current()->PostTask( | 611 base::MessageLoopProxy::current()->PostTask( |
590 FROM_HERE, base::Bind(callback, error, moved_file_path)); | 612 FROM_HERE, base::Bind(callback, error, moved_file_path)); |
591 } | 613 } |
592 } | 614 } |
593 | 615 |
| 616 void GDataDirectoryService::RemoveEntryFromParent( |
| 617 GDataEntry* entry, |
| 618 const FileMoveCallback& callback) { |
| 619 GDataDirectory* parent = entry->parent(); |
| 620 DCHECK(parent); |
| 621 DVLOG(1) << "RemoveEntryFromParent " << entry->GetFilePath().value(); |
| 622 |
| 623 parent->RemoveEntry(entry); |
| 624 if (!callback.is_null()) { |
| 625 base::MessageLoopProxy::current()->PostTask(FROM_HERE, |
| 626 base::Bind(callback, GDATA_FILE_OK, parent->GetFilePath())); |
| 627 } |
| 628 } |
| 629 |
594 void GDataDirectoryService::AddEntryToResourceMap(GDataEntry* entry) { | 630 void GDataDirectoryService::AddEntryToResourceMap(GDataEntry* entry) { |
595 // GDataFileSystem has already locked. | 631 // GDataFileSystem has already locked. |
596 DVLOG(1) << "AddEntryToResourceMap " << entry->resource_id(); | 632 DVLOG(1) << "AddEntryToResourceMap " << entry->resource_id(); |
597 resource_map_.insert(std::make_pair(entry->resource_id(), entry)); | 633 resource_map_.insert(std::make_pair(entry->resource_id(), entry)); |
598 } | 634 } |
599 | 635 |
600 void GDataDirectoryService::RemoveEntryFromResourceMap(GDataEntry* entry) { | 636 void GDataDirectoryService::RemoveEntryFromResourceMap(GDataEntry* entry) { |
601 // GDataFileSystem has already locked. | 637 // GDataFileSystem has already locked. |
602 resource_map_.erase(entry->resource_id()); | 638 resource_map_.erase(entry->resource_id()); |
603 } | 639 } |
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
727 GDataDirectory* entry_parent = old_entry ? old_entry->parent() : NULL; | 763 GDataDirectory* entry_parent = old_entry ? old_entry->parent() : NULL; |
728 if (entry_parent) { | 764 if (entry_parent) { |
729 DCHECK_EQ(fresh_file->resource_id(), old_entry->resource_id()); | 765 DCHECK_EQ(fresh_file->resource_id(), old_entry->resource_id()); |
730 DCHECK(old_entry->AsGDataFile()); | 766 DCHECK(old_entry->AsGDataFile()); |
731 | 767 |
732 entry_parent->RemoveEntry(old_entry); | 768 entry_parent->RemoveEntry(old_entry); |
733 entry_parent->AddEntry(fresh_file.release()); | 769 entry_parent->AddEntry(fresh_file.release()); |
734 } | 770 } |
735 } | 771 } |
736 | 772 |
| 773 void GDataDirectoryService::RefreshDirectory( |
| 774 const std::string& directory_resource_id, |
| 775 const ResourceMap& file_map, |
| 776 const FileMoveCallback& callback) { |
| 777 DCHECK(!callback.is_null()); |
| 778 GetEntryByResourceIdAsync( |
| 779 directory_resource_id, |
| 780 base::Bind(&GDataDirectoryService::RefreshDirectoryInternal, |
| 781 file_map, |
| 782 callback)); |
| 783 } |
| 784 |
| 785 // static |
| 786 void GDataDirectoryService::RefreshDirectoryInternal( |
| 787 const ResourceMap& file_map, |
| 788 const FileMoveCallback& callback, |
| 789 GDataEntry* directory_entry) { |
| 790 DCHECK(!callback.is_null()); |
| 791 |
| 792 if (!directory_entry || !directory_entry->AsGDataDirectory()) { |
| 793 LOG(ERROR) << "RefreshDirectoryInternal: Failed to find directory"; |
| 794 return; |
| 795 } |
| 796 |
| 797 GDataDirectory* directory = directory_entry->AsGDataDirectory(); |
| 798 |
| 799 directory->RemoveChildFiles(); |
| 800 // Add files from file_map. |
| 801 for (ResourceMap::const_iterator it = file_map.begin(); |
| 802 it != file_map.end(); ++it) { |
| 803 scoped_ptr<GDataEntry> entry(it->second); |
| 804 // Skip if it's not a file (i.e. directory). |
| 805 if (!entry->AsGDataFile()) |
| 806 continue; |
| 807 directory->AddEntry(entry.release()); |
| 808 } |
| 809 |
| 810 callback.Run(GDATA_FILE_OK, directory->GetFilePath()); |
| 811 } |
| 812 |
737 void GDataDirectoryService::InitFromDB( | 813 void GDataDirectoryService::InitFromDB( |
738 const FilePath& db_path, | 814 const FilePath& db_path, |
739 base::SequencedTaskRunner* blocking_task_runner, | 815 base::SequencedTaskRunner* blocking_task_runner, |
740 const FileOperationCallback& callback) { | 816 const FileOperationCallback& callback) { |
741 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 817 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
742 DCHECK(!db_path.empty()); | 818 DCHECK(!db_path.empty()); |
743 DCHECK(blocking_task_runner); | 819 DCHECK(blocking_task_runner); |
744 | 820 |
745 if (directory_service_db_.get()) { | 821 if (directory_service_db_.get()) { |
746 if (!callback.is_null()) | 822 if (!callback.is_null()) |
(...skipping 448 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1195 DCHECK(result.get()); | 1271 DCHECK(result.get()); |
1196 | 1272 |
1197 result->second.path = second_path; | 1273 result->second.path = second_path; |
1198 result->second.error = error; | 1274 result->second.error = error; |
1199 result->second.proto = entry_proto.Pass(); | 1275 result->second.proto = entry_proto.Pass(); |
1200 | 1276 |
1201 callback.Run(result.Pass()); | 1277 callback.Run(result.Pass()); |
1202 } | 1278 } |
1203 | 1279 |
1204 } // namespace gdata | 1280 } // namespace gdata |
OLD | NEW |