Home | History | Annotate | Download | only in drive_backend
      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