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); |
| 593 DCHECK(!callback.is_null()); |
572 | 594 |
573 if (entry->parent()) | 595 if (entry->parent()) |
574 entry->parent()->RemoveChild(entry); | 596 entry->parent()->RemoveChild(entry); |
575 | 597 |
576 GDataEntry* destination = FindEntryByPathSync(directory_path); | 598 GDataEntry* destination = FindEntryByPathSync(directory_path); |
577 FilePath moved_file_path; | 599 FilePath moved_file_path; |
578 GDataFileError error = GDATA_FILE_ERROR_FAILED; | 600 GDataFileError error = GDATA_FILE_ERROR_FAILED; |
579 if (!destination) { | 601 if (!destination) { |
580 error = GDATA_FILE_ERROR_NOT_FOUND; | 602 error = GDATA_FILE_ERROR_NOT_FOUND; |
581 } else if (!destination->AsGDataDirectory()) { | 603 } else if (!destination->AsGDataDirectory()) { |
582 error = GDATA_FILE_ERROR_NOT_A_DIRECTORY; | 604 error = GDATA_FILE_ERROR_NOT_A_DIRECTORY; |
583 } else { | 605 } else { |
584 destination->AsGDataDirectory()->AddEntry(entry); | 606 destination->AsGDataDirectory()->AddEntry(entry); |
585 moved_file_path = entry->GetFilePath(); | 607 moved_file_path = entry->GetFilePath(); |
586 error = GDATA_FILE_OK; | 608 error = GDATA_FILE_OK; |
587 } | 609 } |
588 if (!callback.is_null()) { | 610 DVLOG(1) << "MoveEntryToDirectory " << moved_file_path.value(); |
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 } |
| 614 |
| 615 void GDataDirectoryService::RemoveEntryFromParent( |
| 616 GDataEntry* entry, |
| 617 const FileMoveCallback& callback) { |
| 618 GDataDirectory* parent = entry->parent(); |
| 619 DCHECK(parent); |
| 620 DCHECK(!callback.is_null()); |
| 621 DVLOG(1) << "RemoveEntryFromParent " << entry->GetFilePath().value(); |
| 622 |
| 623 parent->RemoveEntry(entry); |
| 624 base::MessageLoopProxy::current()->PostTask(FROM_HERE, |
| 625 base::Bind(callback, GDATA_FILE_OK, parent->GetFilePath())); |
592 } | 626 } |
593 | 627 |
594 void GDataDirectoryService::AddEntryToResourceMap(GDataEntry* entry) { | 628 void GDataDirectoryService::AddEntryToResourceMap(GDataEntry* entry) { |
595 // GDataFileSystem has already locked. | 629 // GDataFileSystem has already locked. |
596 DVLOG(1) << "AddEntryToResourceMap " << entry->resource_id(); | 630 DVLOG(1) << "AddEntryToResourceMap " << entry->resource_id(); |
597 resource_map_.insert(std::make_pair(entry->resource_id(), entry)); | 631 resource_map_.insert(std::make_pair(entry->resource_id(), entry)); |
598 } | 632 } |
599 | 633 |
600 void GDataDirectoryService::RemoveEntryFromResourceMap(GDataEntry* entry) { | 634 void GDataDirectoryService::RemoveEntryFromResourceMap(GDataEntry* entry) { |
601 // GDataFileSystem has already locked. | 635 // GDataFileSystem has already locked. |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
727 GDataDirectory* entry_parent = old_entry ? old_entry->parent() : NULL; | 761 GDataDirectory* entry_parent = old_entry ? old_entry->parent() : NULL; |
728 if (entry_parent) { | 762 if (entry_parent) { |
729 DCHECK_EQ(fresh_file->resource_id(), old_entry->resource_id()); | 763 DCHECK_EQ(fresh_file->resource_id(), old_entry->resource_id()); |
730 DCHECK(old_entry->AsGDataFile()); | 764 DCHECK(old_entry->AsGDataFile()); |
731 | 765 |
732 entry_parent->RemoveEntry(old_entry); | 766 entry_parent->RemoveEntry(old_entry); |
733 entry_parent->AddEntry(fresh_file.release()); | 767 entry_parent->AddEntry(fresh_file.release()); |
734 } | 768 } |
735 } | 769 } |
736 | 770 |
| 771 void GDataDirectoryService::RefreshDirectory( |
| 772 const std::string& directory_resource_id, |
| 773 const ResourceMap& file_map, |
| 774 const FileMoveCallback& callback) { |
| 775 DCHECK(!callback.is_null()); |
| 776 GetEntryByResourceIdAsync( |
| 777 directory_resource_id, |
| 778 base::Bind(&GDataDirectoryService::RefreshDirectoryInternal, |
| 779 file_map, |
| 780 callback)); |
| 781 } |
| 782 |
| 783 // static |
| 784 void GDataDirectoryService::RefreshDirectoryInternal( |
| 785 const ResourceMap& file_map, |
| 786 const FileMoveCallback& callback, |
| 787 GDataEntry* directory_entry) { |
| 788 DCHECK(!callback.is_null()); |
| 789 |
| 790 if (!directory_entry) { |
| 791 callback.Run(GDATA_FILE_ERROR_NOT_FOUND, FilePath()); |
| 792 return; |
| 793 } |
| 794 |
| 795 GDataDirectory* directory = directory_entry->AsGDataDirectory(); |
| 796 if (!directory) { |
| 797 callback.Run(GDATA_FILE_ERROR_NOT_A_DIRECTORY, FilePath()); |
| 798 return; |
| 799 } |
| 800 |
| 801 directory->RemoveChildFiles(); |
| 802 // Add files from file_map. |
| 803 for (ResourceMap::const_iterator it = file_map.begin(); |
| 804 it != file_map.end(); ++it) { |
| 805 scoped_ptr<GDataEntry> entry(it->second); |
| 806 // Skip if it's not a file (i.e. directory). |
| 807 if (!entry->AsGDataFile()) |
| 808 continue; |
| 809 directory->AddEntry(entry.release()); |
| 810 } |
| 811 |
| 812 callback.Run(GDATA_FILE_OK, directory->GetFilePath()); |
| 813 } |
| 814 |
737 void GDataDirectoryService::InitFromDB( | 815 void GDataDirectoryService::InitFromDB( |
738 const FilePath& db_path, | 816 const FilePath& db_path, |
739 base::SequencedTaskRunner* blocking_task_runner, | 817 base::SequencedTaskRunner* blocking_task_runner, |
740 const FileOperationCallback& callback) { | 818 const FileOperationCallback& callback) { |
741 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 819 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
742 DCHECK(!db_path.empty()); | 820 DCHECK(!db_path.empty()); |
743 DCHECK(blocking_task_runner); | 821 DCHECK(blocking_task_runner); |
744 | 822 |
745 if (directory_service_db_.get()) { | 823 if (directory_service_db_.get()) { |
746 if (!callback.is_null()) | 824 if (!callback.is_null()) |
(...skipping 448 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1195 DCHECK(result.get()); | 1273 DCHECK(result.get()); |
1196 | 1274 |
1197 result->second.path = second_path; | 1275 result->second.path = second_path; |
1198 result->second.error = error; | 1276 result->second.error = error; |
1199 result->second.proto = entry_proto.Pass(); | 1277 result->second.proto = entry_proto.Pass(); |
1200 | 1278 |
1201 callback.Run(result.Pass()); | 1279 callback.Run(result.Pass()); |
1202 } | 1280 } |
1203 | 1281 |
1204 } // namespace gdata | 1282 } // namespace gdata |
OLD | NEW |