1 // Copyright 2013 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/sync_file_system/drive_backend/folder_creator.h" 6 7 #include "chrome/browser/drive/drive_api_util.h" 8 #include "chrome/browser/drive/drive_service_interface.h" 9 #include "chrome/browser/sync_file_system/drive_backend/drive_backend_util.h" 10 #include "chrome/browser/sync_file_system/drive_backend/metadata_database.h" 11 #include "google_apis/drive/drive_api_parser.h" 12 #include "google_apis/drive/gdata_wapi_parser.h" 13 14 namespace drive { 15 class DriveServiceInterface; 16 class DriveUploaderInterface; 17 } 18 19 namespace google_apis { 20 class ResourceEntry; 21 class ResourceList; 22 } 23 24 namespace sync_file_system { 25 namespace drive_backend { 26 27 FolderCreator::FolderCreator(drive::DriveServiceInterface* drive_service, 28 MetadataDatabase* metadata_database, 29 const std::string& parent_folder_id, 30 const std::string& title) 31 : drive_service_(drive_service), 32 metadata_database_(metadata_database), 33 parent_folder_id_(parent_folder_id), 34 title_(title), 35 weak_ptr_factory_(this) { 36 } 37 38 FolderCreator::~FolderCreator() { 39 } 40 41 void FolderCreator::Run(const FileIDCallback& callback) { 42 drive_service_->AddNewDirectory( 43 parent_folder_id_, 44 title_, 45 drive::DriveServiceInterface::AddNewDirectoryOptions(), 46 base::Bind(&FolderCreator::DidCreateFolder, 47 weak_ptr_factory_.GetWeakPtr(), callback)); 48 } 49 50 void FolderCreator::DidCreateFolder( 51 const FileIDCallback& callback, 52 google_apis::GDataErrorCode error, 53 scoped_ptr<google_apis::FileResource> entry) { 54 SyncStatusCode status = GDataErrorCodeToSyncStatusCode(error); 55 if (status != SYNC_STATUS_OK) { 56 callback.Run(std::string(), status); 57 return; 58 } 59 60 drive_service_->SearchByTitle( 61 title_, parent_folder_id_, 62 base::Bind(&FolderCreator::DidListFolders, 63 weak_ptr_factory_.GetWeakPtr(), callback, 64 base::Passed(ScopedVector<google_apis::FileResource>()))); 65 } 66 67 void FolderCreator::DidListFolders( 68 const FileIDCallback& callback, 69 ScopedVector<google_apis::FileResource> candidates, 70 google_apis::GDataErrorCode error, 71 scoped_ptr<google_apis::FileList> file_list) { 72 SyncStatusCode status = GDataErrorCodeToSyncStatusCode(error); 73 if (status != SYNC_STATUS_OK) { 74 callback.Run(std::string(), status); 75 return; 76 } 77 78 if (!file_list) { 79 NOTREACHED(); 80 callback.Run(std::string(), SYNC_STATUS_FAILED); 81 return; 82 } 83 84 candidates.reserve(candidates.size() + file_list->items().size()); 85 candidates.insert(candidates.end(), 86 file_list->items().begin(), 87 file_list->items().end()); 88 file_list->mutable_items()->weak_clear(); 89 90 if (!file_list->next_link().is_empty()) { 91 drive_service_->GetRemainingFileList( 92 file_list->next_link(), 93 base::Bind(&FolderCreator::DidListFolders, 94 weak_ptr_factory_.GetWeakPtr(), callback, 95 base::Passed(&candidates))); 96 return; 97 } 98 99 const google_apis::FileResource* oldest = NULL; 100 for (size_t i = 0; i < candidates.size(); ++i) { 101 const google_apis::FileResource& entry = *candidates[i]; 102 if (!entry.IsDirectory() || entry.labels().is_trashed()) 103 continue; 104 105 if (!oldest || oldest->created_date() > entry.created_date()) 106 oldest = &entry; 107 } 108 109 if (!oldest) { 110 callback.Run(std::string(), SYNC_FILE_ERROR_NOT_FOUND); 111 return; 112 } 113 114 std::string file_id = oldest->file_id(); 115 116 metadata_database_->UpdateByFileResourceList( 117 candidates.Pass(), base::Bind(&FolderCreator::DidUpdateDatabase, 118 weak_ptr_factory_.GetWeakPtr(), 119 file_id, callback)); 120 } 121 122 void FolderCreator::DidUpdateDatabase(const std::string& file_id, 123 const FileIDCallback& callback, 124 SyncStatusCode status) { 125 if (status != SYNC_STATUS_OK) { 126 callback.Run(std::string(), status); 127 return; 128 } 129 130 DCHECK(!file_id.empty()); 131 if (!metadata_database_->FindFileByFileID(file_id, NULL)) { 132 callback.Run(std::string(), SYNC_FILE_ERROR_NOT_FOUND); 133 return; 134 } 135 136 callback.Run(file_id, status); 137 } 138 139 } // namespace drive_backend 140 } // namespace sync_file_system 141